一对一:未定义的方法构建

时间:2012-02-29 11:54:40

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

遇到一对一关系的问题

我有一些比赛,我希望得到一个比赛的分数。

我的Match.rb

has_one :score, :dependent => :destroy

my score.rb

belongs_to :match

my scores_controller.rb

def new
@match = Match.find(params[:match_id])
@score = @match.score.new
end

def create
@match = Match.find(params[:match_id])
@score = @match.score.create(params[:score])
end

my routes.rb

resources :matches do
resources :scores
end

我的分数/ new.html.haml

= form_for([@match, @match.score.build]) do |f|
    = f.label :score1
    = f.text_field :score1
    %br
    = f.label :score2
    =f.text_field :score2
    %br
    = f.submit

我的错误

undefined method `new' for nil:NilClass

到目前为止,我还没有处理过一对一的关系,因为我对RoR很新,有什么建议吗?

修改

编辑我的代码以匹配create_score和build_score,似乎工作。但现在我有一些奇怪的行为。

在我的score.rb

attr_accessible :score1, :score2

但是当我尝试在我的匹配/ show.html.haml

中调用时
= @match.score.score1

我得到一个未知的方法调用或者根本没有看到任何东西......但是如果我只是打电话

= @match.score

我得到一个得分对象(例如#)#

编辑2

修复问题。我在打电话

分数/ new.haml.html

= form_for([@match, @match.create_score])

需要

= form_for([@match, @match.build_score])

一切都按预期运作。

需要输入rails console并获取这些对象以查看每个:score1:score2为nil

3 个答案:

答案 0 :(得分:25)

使用build代替new

def new
    @match = Match.find(params[:match_id])
    @score = @match.build_score
end

以下是这方面的文档:http://guides.rubyonrails.org/association_basics.html#belongs_to-build_association

同样,在create方法中,这样做:

def create
    @match = Match.find(params[:match_id])
    @score = @match.create_score(params[:score])
end

文档:http://guides.rubyonrails.org/association_basics.html#belongs_to-create_association

答案 1 :(得分:8)

你应该做match.build_score。这是因为当您调用score方法时,它会尝试获取关联,并且因为它尚未定义,它将返回nil。然后,您在build上致电nil,这就是它爆炸的原因。

has_many关联方法将一种“代理”对象返回给调用它们返回的对象,因此这就是posts.comments.build之类的工作原理。 belongs_tohas_one关联的方法尝试直接获取关联,因此您需要build_association而不是association.build

答案 2 :(得分:5)

您可以使用以下示例

创建乐谱
@match.build_score
or
@match.create_score