1

私には複数の子供を持つ親がいます。フォームを送信すると、親モデルで親が生成され、子モデルで子ごとに 1 つずつ複数のレコードが作成されるようにします。送信しようとすると、次のエラーが表示されます。

 ActiveRecord::AssociationTypeMismatch in ParentsController#create

   Child(#) expected, got Array(#)

accept_nested_attributes_for :children のコメントを外し、f.fields_for :children を f.fields_for :children_attributes に変更すると、別のエラーが発生します。

  TypeError in ParentsController#create

    can't convert Symbol into Integer

私は何をすべきか途方に暮れています。ネストされたモデル フォームの Railscast をチェックアウトしましたが、それらはフォーム内での子フィールドの生成を処理しており、Railscast から学んだことは機能していないようです。私は自分の builder.text_field :cname のフォームが間違っていますが、それを行う適切な方法を知りません。

私のコード:

親.rb

class Parent < ActiveRecord::Base
  has_many :children
  #accepts_nested_attributes_for :children
  attr_protected :id

child.rb

class Child < ActiveRecord::Base
  belongs_to :parent
  attr_protected :id

_form.html.erb

<%= form_for @parent, :url => { :action => "create" } do |f| %>
  <%= f.text_field :pname %>
  <%= f.fields_for :children do |builder| %>
    <%= builder.text_field :cname %>
    <%= builder.text_field :cname %>
    <%= builder.text_field :cname %>
  <% end %>
  <%= f.submit %>
<% end %>

パラメータの内容:

{"utf8"=>"✓",
 "authenticity_token"=>"FQQ1KdNnxLXolfes9IGiO+aKHJaPCH+2ltDdA0TwF7w=",
 "parent"=>{"pname"=>"Heman",
 "child"=>{"cname"=>""}},
 "commit"=>"Create"}
4

1 に答える 1

4

ここでの問題は、HTML で生成された子用のフォームが、params ハッシュ (params[:parent][:child][:cname]ペアを使用) で同じ「場所」(同じペアのキー/値) を使用していることです。これが、Params ハッシュの「子」ノードにパラメータ「名前」が 1 つしかない理由です。

それを避けるために、入力の名前に配列を使用できます。

<input type="text" name="child[][cname]" />
<input type="text" name="child[][cname]" />

これが送信されると、params は次のようになります。

params: {
  child: [ { cname: 'blabla' }, { cname: 'bonjour' } ]
}

あなたの場合、望ましい結果を得るには:

<%= form_for @parent, :url => { :action => "create" } do |f| %>
  <%= f.text_field :pname %>

  <%= text_field_tag "parent[children][][cname]" %>
  <%= text_field_tag "parent[children][][cname]" %>
  <%= text_field_tag "parent[children][][cname]" %>

  <%= f.submit %>
<% end %>

次のようなものを生成する必要があります。

{
  "utf8"=>"✓",
  "authenticity_token"=>"FQQ1KdNnxLXolfes9IGiO+aKHJaPCH+2ltDdA0TwF7w=",
  "parent"=> { 
    "pname"=>"Heman",
    "children"=> [
      { "cname"=>"SisiSenior" },
      { "cname"=>"Bonjor" },
      { "cname"=>"Blabla" }
    ]
  },
  "commit"=>"Create"}

したがって、コントローラーでは、次のようなものを使用できます。

#ParentsController
def create
  children_attributes = params[:parent].delete(:children) # takes off the attributes of the children
  @parent = Parent.create(params[:parent])

  children_attributes.each do |child_attributes|
    child = @parent.children.create(child_attributes)
  end
end
于 2013-07-03T18:15:56.897 に答える