web-dev-qa-db-ja.com

Rails 4ネストされた属性を更新

更新の代わりにネストされた属性の追加を更新すると、使用しようとしている多くの関係がありますRails 4 Update_attributes

Class Person <ActiveRecord::Base
 has_many :pets
 accepts_nested_attributes_for :pets
end

Class Pet < ActiveRecord::Base
 belongs_to :person
end

私のコントローラーでは、パラメーターを{id:23、house_no: '22A'、pets:[{name: 'jeffy'、type: 'dog'}、{name: 'sharky'、type: 'fish'}として受信しています。 ]}

私の更新方法は

def update
  @Person = Person.find(params[:id])
  if @Person.update(person_params)
    @Person.save
    render 'persons/create', status 200
  else
    render 'persons/create', status 400
  end
end

private
def person_params
  person_params = params.permit(:house_no)
  person_params.merge! ({pets_attributes: params[:pets]}) if params[:pets].present?
  person_params
end

今、私がそれを更新し、その人がすでにペットを持っている場合、ID 1の人が「タイガー」という名前の1つのペットを持ち、「シャシャ」という名前の2つのペットでその人を更新し、 「Monti」の場合、個人レコードには2(ShashaおよびMonti)に更新する代わりに、3つのペット(Tiger、ShashaおよびMonti)があります。

23
Kush Jain

マニュアルを参照してください:

http://api.rubyonrails.org/v4.0.1/classes/ActiveRecord/NestedAttributes/ClassMethods.html

pets_attributes:[{name:'jeffy', type:'dog'}, {name:'sharky', type:'fish'}]などの属性を送信する必要があります

正常に機能するはずです。

読んでください

メンバーの属性ハッシュを使用して、関連する投稿の属性を設定または更新できるようになりました:投稿属性のハッシュの配列を値としてキー:posts_attributesを含めます。idキーを持たないハッシュごとに新しいレコードが作成されますハッシュにtrueと評価される_destroyキーも含まれていない限り、インスタンス化されます。

15
Suchit Puri

Personモデルを次のように更新します。

class Person < ActiveRecord::Base  ## NOTE: class (c lowercase) and NOT Class
 has_many :pets
 accepts_nested_attributes_for :pets, allow_destroy: true  ## Added allow_destroy
end

関連するモデル、つまり属性ハッシュを介してPetを破棄するには、最初に:allow_destroyオプションを使用して有効にする必要があります。

次に、ビューから、削除するペットの_destroy属性を渡す必要があります。

以来、ビュー固有のコードを共有していません。次に、ビューでの実装方法の例を示します。要件に応じて変更します。

<%= form_for @person do |f| %>
  <%## .. %>  
  <%= f.fields_for :pets do |builder| %>
    <%## .. %>    
    <%= builder.check_box :_destroy %>
    <%= builder.label :_destroy, "Remove Pet" %>
  <% end %>
<% end %>

上記のコードでは、_destroy値を渡すためにcheckboxlabelを追加する必要があります。

この後、コントローラーのperson_paramsメソッドを以下のように更新します。

def person_params
  params.require(:person).permit(:house_no, pets_attributes: [:id, :name, :type, :person_id, :_destroy])
end 

注:

するべきではないinstance variables大文字で定義する。大文字の名前は、ConstantsRubyを宣言するために使用されます。

def update
  @person = Person.find(params[:id])
  if @person.update(person_params)
    @person.save
    render 'persons/create', status 200
  else
    render 'persons/create', status 400
  end
end  
14
Kirti Thorat

:id属性を:pets_attributesperson_params配列に追加してみてください。

Id属性を許可する必要があります。

12

おそらく1.ペットを個別に割り当てたい場合、

@Person.pets = Pets.find(params[:pets])

または2. Personを保存する前にペットを片付けます。

@Person.pets.destroy

あなたはペットの属性でパラメータを編集する必要があります

また、ペットオブジェクトに:idパラメータを追加する必要があります。

1
faisal bhatti

person_paramsを次のように変更してみてください

def person_params
  person_params = params.require(:person).permit(:house_no ,pets_attributes: [:name,:type])
end

そして、更新メソッドから@person.saveを削除します。必要ありません。また、updateには!を使用します

def update
  @Person = Person.find(params[:id])
  if @Person.update!(person_params)
    render 'persons/create', status 200
  else
    render 'persons/create', status 400
  end
end

更新

また、Petモデルにはbelongs_to :personアソシエーションがありません。モデルに追加してください

Class Pet < ActiveRecord::Base

belongs_to :person

end

そして今、paramsに追加することでperson_id属性を許可します

def person_params
  person_params = params.require(:person).permit(:house_no,pets_attributes: [:name,:type,:person_id])
end
1
Pavan