2011-05-09 56 views
12

我的嵌套模型表单在第一层深处工作良好。但我的印象是,你可以使用accept_nested_attributes_for深入多层次。但是,当我尝试下面的代码时,“图像”属性被附加到顶级“问题”模型,并且在表单提交时中断了未知属性“图像”错误。Rails 3嵌套模型表单,使用位于深层的两个级别accep_nested_attributes_for

我可以使用表单数据手工完成插入操作,但是如果Rails能够自动处理它,那么显而易见的原因会更好。

我在做什么错?我试着改变| af |在“字段为:图像做”到它自己的唯一名称,但它没有任何作用。

型号:

class Question < ActiveRecord::Base 
    has_one :answer 
    accepts_nested_attributes_for :answer 
end 

class Answer < ActiveRecord::Base 
    belongs_to :question 
    has_one :image 
    accepts_nested_attributes_for :image 
end 

class Image < ActiveRecord::Base 
    belongs_to :answer 
end 

控制器:

def new 
    @question = Question.new 
    answer = @question.build_answer 
    image = answer.build_image 

    @case_id = params[:id] 

    render :layout => 'application', :template => '/questions/form' 
end 

def create 
    question_data = params[:question] 
    @question = Question.new(question_data) 
    if @question.save 
    ... 
end 

查看:

= form_for @question, :html => {:multipart => true} do |f| 

    = f.label :text, "Question Text:" 
    = f.text_area :text, :rows => 7 

    %br 
    %br 

    =f.fields_for :answer, do |af| 
    = af.label :body, "Answer Text:" 
    = af.text_area :body, :rows => 7 

    %br 
    %br 

    = f.fields_for :image do |af| 
     = af.label :title, "Image Title:" 
     = af.text_field :title 

     %br 

     = af.label :file, "Image File:" 
     = af.file_field :file 

     %br 

     = af.label :caption, "Image Caption:" 
     = af.text_area :caption, :rows => 7 

    = hidden_field_tag("case_id", value = @case_id) 

    = f.submit 

回答

8

我想你已经得到了表单变量稍微混合起来。它应该是:

= form_for @question, :html => {:multipart => true} do |f| 

    = f.label :text, "Question Text:" 
    = f.text_area :text, :rows => 7 

    %br 
    %br 

    =f.fields_for :answer, do |af| 
    = af.label :body, "Answer Text:" 
    = af.text_area :body, :rows => 7 

    %br 
    %br 

    = af.fields_for :image do |img_form| 
     = img_form.label :title, "Image Title:" 
     = img_form.text_field :title 

     %br 

     = img_form.label :file, "Image File:" 
     = img_form.file_field :file 

     %br 

     = img_form.label :caption, "Image Caption:" 
     = img_form.text_area :caption, :rows => 7 

    = hidden_field_tag("case_id", value = @case_id) 

    = f.submit 

注意如何form_for ... do |f|滋生f.fields_for ... do |af|,这又滋生af.fields_for ... do |img_form|

关键是第二个fields_for。它应该是af.fields_for :image do |img_form|而不是f.fields_for :image do |img_form|

+1

谢谢,解决了这个问题。我现在唯一的问题是,当我提交表单时,我收到表单错误“回答问题不能为空”。我猜这是因为“答案”有一个名为question_id的必填字段,似乎可能没有填写。有任何想法吗? – LennonR 2011-05-09 18:15:36

+2

这是正确的。这是因为父对象('Question')是一个新记录,所以当你试图保存一个子对象('Answer')时它还不存在(即没有一个id)。你可以在你的控制器或者控制器上删除你的验证,首先保存父对象('@ question.save'),然后保存孩子('@question.answers << @ answer')。像这样的东西...欲了解更多信息,请查看[文章](http://hobocentral.net/blog/2008/04/29/activerecord-behaviour-with-associations/)。 HTH – mbreining 2011-05-09 18:57:00

+0

它真的不能算出来吗?在下面的Railscast中(尽管Rails 2.3)作者用简单的@ survey.new/@ survey.save来做我想做的事情。对于他来说,Rails只是把它全部弄清楚了,并且正确地做了关联。 Rails 3是否真的不再处理这个问题?这里是他的项目的github源代码:[link](https://github.com/ryanb/railscasts-episodes/tree/master/episode-196/surveysays)或者我正在做一些不同的事情? – LennonR 2011-05-09 19:36:00