Controller#action中的NoMethodError - #<user:0x007fba0e32f760> </user:0x007fba0e32f760>的未定义方法`keynote'>

时间:2011-11-05 19:13:01

标签: ruby-on-rails ruby-on-rails-3 routes

我正在构建一个具有Keynote模型和Story模型的应用程序(以及我用Devise实现的用户模型)。主题演讲有许多故事和一个故事属于主题演讲。

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

  

StoriesController中的NoMethodError #create

     

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

错误发生在stories_controller.rb的第18行,即

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

在create方法中。

这是我的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

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”=&gt; “中✓”,   “authenticity_token”=&gt; “中76odSpcfpTlnePxr + WBt36fVdiLD2z + Gnkxt / EU1 / TU =”,   “keynote_id”=&gt;“1”,“story”=&gt; {“name”=&gt;“嗨?”},“提交”=&gt;“提问”}

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

  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])。这引发了一个不同的错误:

  

路由错误

     

没有路线匹配{:controller =&gt;“故事”}

但创建了数据库中的记录,但没有user_id。

任何帮助都会非常感激。

更新:这是我的用户模型,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模型:

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

这是故事.rb模型:

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

1 个答案:

答案 0 :(得分:3)

发生错误是因为没有keynote,但是keynotes。如果您只想向用户添加一个故事,请删除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])

因为主题演讲已经属于某个用户。你应该始终把你的范围 关联。所以,而不是:

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

做的:

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

这样,您就知道您总是为当前用户找到主题演讲。如果黑客发送了参数keynote_id = 55,但55不属于current_user,则表示黑客能够将故事与可能没有主题的主题演讲相关联。

我只是猜测你不想允许在属于其他用户的主题演讲中添加故事。