Rails嵌套对象表单* _attributes

时间:2009-04-12 22:21:28

标签: ruby-on-rails nested-forms

我正在使用Rails 2.3.2,并尝试使嵌套对象表单正常工作。我已经将我的问题缩小到Rails未设置我的嵌套表单元素以及启动accepts_nested_attributes_for处理所需的* _attributes的问题。

我的型号代码是:

class Person < Party
  has_one :name, :class_name => "PersonName"
  accepts_nested_attributes_for :name, :allow_destroy => true
end

class PersonName < ActiveRecord::Base
  belongs_to :person
end

我的视图代码看起来像这样(我正在使用HAML):

%h3 New customer
= error_messages_for :person, :person_name, :name, :country

- form_for :person, :url => collection_url, :html => {:class => 'MainForm'} do |person_form|

  - @person.build_name unless @person.name
  - person_form.fields_for :name do |name_form|
    = name_form.label :given_name, "First Name:"
    = name_form.text_field :given_name

    = name_form.label :family_name, "Last Name:"
    = name_form.text_field :family_name

  = hidden_field_tag :inviter_id, params[:inviter_id]
  = hidden_field_tag :inviter_code, params[:inviter_code]
  %p= submit_tag "Create"

= link_to 'Back', collection_url

而不是params:

{"person"=>{"name_attributes"=>{"given_name"=>"Fred", "family_name"=>"Flintstone"}}, ...} 

我明白了:

{"person"=>{"name"=>{"given_name"=>"Fred", "family_name"=>"Flintstone"}}, ...} 

结果,我得到了一个TypeMismatch异常。我已经按照Ryan Daigle的文档进行了操作。我也遵循了this blogcomplex-forms-example的建议。

使用Firebug,我浏览了表单并将输入标记的name属性从name调整为name_attributes。这产生了带有name_attributes的参数,并且创建工作正常。

我陷入困境,因为我无法弄清楚为什么我的表单没有生成名称的* _attributes形式。

我尝试的另一件事是我在我的环境中使用complex_form_example。我已经浏览了控制器,模型和视图的每一寸,并将其与我的代码进行了比较。我找不到有什么不同。我知道这很小,感谢任何帮助!

谢谢!

6 个答案:

答案 0 :(得分:4)

尝试使用form_for的实际对象:

form_for :person => form_for @person

答案 1 :(得分:4)

回帖不会被送到正确的地方

def new
  @person = Person.new
end

<% form_for @person do |f| %>
    <% f.fields_for :name_attributes do |p| %>
        ...
    <% end %>
<% end %>

回发邮件被送到正确的地方

def new
  @person = Person.new
  @person.name = PersonName.new # << this allows fields_for :relation vs :relation_attributes
end

<% form_for @person do |f| %>
    <% f.fields_for :name do |p| %>
        ...
    <% end %>
<% end %>

#create

中不需要@ person.name

答案 2 :(得分:1)

我刚刚在同一个问题上苦苦挣扎了一个小时!

按照nowk的模式在控制器中使用新方法,然后将其放在视图中

<% form.fields_for :name, @person.name do |name_form| %>


<% end %>

祝你好运,如果你尝试的话,这对我有用。

答案 3 :(得分:0)

不确定为什么这不起作用,但作为解决方法,您可以在控制器#create方法中使用params [:name]来更新人员记录。

person = Person.new(params[:person])
person.name << PersonName.new(params[:name])

答案 4 :(得分:0)

不幸的是,我仍然无法弄清楚为什么这种形式不适用于嵌套对象形式。我把它剥离到最简单的数据,开始使用complex-form-example作为开始。我最后使用active_presenter从表单中收集x-object数据。我将在表单中的某个时间重新访问嵌套对象表单。谢谢你的帮助。

答案 5 :(得分:0)

以为我会分享我的解决方案,因为它略有不同 - 在我的情况下,我希望嵌套属性是动态的。

采取新行动:

  case params[:type]
  when "clubber"
    @account = resource.send "build_#{params[:type]}"
  when "promoter"
    @account = resource.send "build_#{params[:type]}"
  when "company"
    @account = resource.send "build_#{params[:type]}"
  when "venue_owner"
    flash[:notice] = 'We ask that venue owners register via the web. Thanks.'
    redirect_to root_path and return
  end

在我看来:

= f.fields_for @account.class.name.downcase+'_attributes' do |form|

漂亮的贫民窟,但它有效。