Controller#action 中的 NoMethodError

编程入门 行业动态 更新时间:2024-10-11 11:23:58
本文介绍了Controller#action 中的 NoMethodError - #<User:0x007fba0e32f760> 的未定义方法`keynote'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在构建一个具有 Keynote 模型和 Story 模型(以及我使用 Devise 实现的 User 模型)的应用程序.Keynote 有很多 Stories,一个 Story 属于一个 Keynote.

I'm building an application that has a Keynote model and a Story model (as well as a User model that I implemented with Devise). Keynotes have many Stories and a Story belongs to a Keynote.

我在创建新故事时遇到问题,并收到以下错误:

I'm having problems creating new stories and I get the following error:

StoriesController#create 中的 NoMethodError

#User:0x007fba0e32f760 的未定义方法`keynote'

undefined method `keynote' for #User:0x007fba0e32f760

错误发生在story_controller.rb的第18行

The error happens on line 18 of stories_controller.rb which is

@story = @current_user.keynote.stories.build(params[:story])

在创建方法中.

这是我的story_controller.rb的一部分

This is part of my stories_controller.rb

class StoriesController < ApplicationController before_filter :authenticate_user!, :except => [:show, :index] def index @keynote = Keynote.find(params[:keynote_id]) @stories = @keynote.stories end def new @keynote = Keynote.find(params[:keynote_id]) @story = @keynote.stories.build end def create if user_signed_in? @keynote = Keynote.find(params[:keynote_id]) @story = @current_user.keynote.stories.build(params[:story]) if @story.save flash[:notice] = 'Question submission succeeded' redirect_to keynote_stories_path else render :action => 'new' end end end

这是我的 keynotes_controller.rb

This is my keynotes_controller.rb

class KeynotesController < ApplicationController def index @keynotes = Keynote.find :all, :order => 'id ASC' end def new @keynote = Keynote.new end def show @keynote = Keynote.find(params[:id]) end def create @keynote = Keynote.new(params[:keynote]) if @keynote.save flash[:notice] = 'Keynote submission succeeded' redirect_to keynotes_path else render :action => 'new' end end end

这些是传递的参数:

{"utf8"=>"✓","authenticity_token"=>"76odSpcfpTlnePxr+WBt36fVdiLD2z+Gnkxt/Eu1/TU=","keynote_id"=>"1", "story"=>{"name"=>"Hi?"}, "commit"=>"Ask"}

{"utf8"=>"✓", "authenticity_token"=>"76odSpcfpTlnePxr+WBt36fVdiLD2z+Gnkxt/Eu1/TU=", "keynote_id"=>"1", "story"=>{"name"=>"Hi?"}, "commit"=>"Ask"}

这就是我在 routes.rb 文件中的内容:

And this is what I have in my routes.rb file:

get "keynotes/index" get "users/show" devise_for :users get "votes/create" get "stories/index" resources :keynotes do resources :stories end resources :stories do get 'bin', :on => :collection resources :votes end resources :users root :to => 'keynotes#index'

我从错误行中删除了 current_user,只留下 @story = @keynote.stories.build(params[:story]).这会引发不同的错误:

I deleted current_userfrom the line with the error, leaving just @story = @keynote.stories.build(params[:story]). This throws a different error:

路由错误

没有路由匹配 {:controller=>"stories"}

No route matches {:controller=>"stories"}

但是数据库中的记录被创建,虽然没有 user_id.

but the record in the database gets created, without the user_id though.

任何帮助将不胜感激.

更新:这是我的用户模型,user.rb

Update: here's my User model, user.rb

class User < ActiveRecord::Base has_many :stories has_many :keynotes has_many :votes has_many :stories_voted_on, :through => :votes, :source => :story # Include default devise modules. Others available are: # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable # Setup accessible (or protected) attributes for your model attr_accessible :email, :password, :password_confirmation, :remember_me end

这是 keynote.rb 模型:

Here's the keynote.rb model:

class Keynote < ActiveRecord::Base validates_presence_of :title, :description, :speaker, :location has_many :stories belongs_to :user end

这是 story.rb 模型:

And here's the story.rb model:

class Story < ActiveRecord::Base after_create :create_initial_vote validates_presence_of :name belongs_to :user belongs_to :keynote has_many :votes do def latest find :all, :order => 'id DESC', :limit => 3 end end protected def create_initial_vote votes.create :user => user end end

推荐答案

出现错误是因为没有keynote,而是keynotes.如果您只想向用户添加故事,请删除 keynote.:

The error occurs because there is no keynote, but is keynotes. If you just want to add a Story to the User, remove the keynote.:

#return keynote even if it does not belong to current user @keynote = Keynote.find(params[:keynote_id]) @story = @current_user.stories.build(params[:story]) #removed `keynote.` part @story.keynote = @keynote #add the keynote to @story before saving @story

您还应该能够:

#return the keynote id only if it belongs to current user @keynote = @current_user.keynotes.find(params[:keynote_id]) @story = @keynote.stories.build(params[:story])

因为主题演讲已经属于某个用户.你应该总是把你的范围协会.所以,而不是这样:

Because the keynote already belongs to a certain user. you should always scope your associations. So, instead of this:

@keynote = Keynote.find(params[:keynote_id])

做:

@keynote = @current_user.keynotes.find(params[:keynote_id])

这样,您就知道您总是在为当前用户找到主题演讲.如果黑客发送了参数 keynote_id = 55,但 55 不属于 current_user,这意味着黑客能够将一个故事与一个可能无意的主题相关联.

This way, you know that you are always finding the keynote for current user. If a hacker send the param keynote_id = 55, but 55 does not belong to current_user, that means the hacker was able to associate a story with an probably-uninteded keynote.

我只是猜测您不想允许向属于其他用户的主题演讲添加故事.

I'm just guessing that you don't want to allow adding a story to a keynote belonging to some other user.

更多推荐

Controller#action 中的 NoMethodError

本文发布于:2023-10-27 23:43:25,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1534876.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:Controller   action   NoMethodError

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!