Rails 3嵌套模型表,使用accepts_nested_attributes_for深入2级

Len*_*onR 12 forms multiple-models ruby-on-rails-3

我的嵌套模型表单在第一级深度工作得很好.但我的印象是你可以使用accepts_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
Run Code Online (Sandbox Code Playgroud)

控制器:

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
Run Code Online (Sandbox Code Playgroud)

视图:

= 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
Run Code Online (Sandbox Code Playgroud)

mbr*_*ing 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
Run Code Online (Sandbox Code Playgroud)

注意如何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|.

  • 那是对的.发生这种情况是因为父对象(`Question`)是一个新记录,所以当你尝试保存子对象(`Answer`)时它还不存在(即没有id).您可以在question_id或控制器中删除验证,首先保存父对象(`@ question.save`),然后保存子项(`@question.answers << @ answer`).类似的东西......有关更多信息,请查看此[文章](http://hobocentral.net/blog/2008/04/29/activerecord-behaviour-with-associations/).HTH (2认同)