web-dev-qa-db-ja.com

ネストされた属性update_attributesは、更新ではなく挿入を使用します

次のようなユーザーとネストされたプロファイルクラスがあります。

class User < ActiveRecord::Base
  has_one :profile
  attr_accessible :profile_attributes
  accepts_nested_attributes_for :profile
end

class Profile < ActiveRecord::Base
  belongs_to :user
  attr_accessible :name
end

user = User.find(1)
user.profile.id  # => 1
user.update_attributes(profile_attributes: {name: 'some name'})
user.profile.id  # => 2

Railsが古いプロファイルを破棄し、新しいプロファイルを作成している理由がわかりません。

使用する

user.profile.update_attributes({name: 'some name'})

期待どおりに現在のプロファイルを更新するだけです。しかし、その場合、私はaccepts_nested_attributes_forを利用していません

更新がこのように行われる理由を誰かが知っていますか?どのユーザーにも接続されていないプロファイル行のデータベースになってしまうことは避けたいと思います。

28
Jason

update_onlyオプションを追加することで、この問題を解決しました。

accepts_nested_attributes_for :profile, update_only: true

これで、新しいプロファイルは、まだ存在しない場合にのみ作成されます。

20
Jason

Rails 4:fields_forは、ネストされたフォームのIDをすでに追加していますが、:idパラメーターを許可する必要があります。:object_name_idパラメーターのみを許可しました。エラーをスローしないでください。サーバーログにこれが表示されるまで、しばらく時間がかかりました。これにより、誰かが私よりも時間を無駄にすることがなくなることを願っています:)

37
irruputuncu

フォームを確認する場合は、Profileオブジェクトのネストされた属性ハッシュ内にid属性を設定する必要があります。 IDが設定されていない場合、ActiveRecordはそれが新しいオブジェクトであると見なします。

たとえば、ユーザー内のネストされたプロファイルのネストされた「profile_attributes」パラメータハッシュを使用して「user」パラメータのセットを構築するERBフォームがある場合、次のようにプロファイルIDの非表示値を含めることができます。

<%= hidden_field "user[profile_attributes][id]", @profile.id %>
23
Winfield

Railsの別のバージョンでこれに見舞われ、気が狂うと思いました。update_only=> trueを追加している間、それはRailsのどこかにあるバグだと思います。

私の場合の症状:belongs_toへの関連付けが削除され、新しいネストされたオブジェクトが作成されます-最初にページを更新するまで。その後、それは正しく機能しました。

私の場合、ネストされたクラスにbefore_saveメソッドを追加し、保存したものを出力しました。また、update_attributesを呼び出す前に属性を出力しました。 「parent_id」が正しく設定されていました。また、フォームに非表示のIDフィールドを含めましたが、変更はありません。これは、fields_for ...を使用してすでに含まれているため正常でした。

驚いたことに、1つの更新呼び出しで2つの保存呼び出しが生成されました。最初の保存にはネストされたオブジェクトIDがありますが、belongs_toIDはnullです。 -したがって、これによりレコードが更新され、「parent_id」がnullに設定されます。 2回目の保存では、「parent_id」が設定されますが、ネストされたオブジェクトIDはnullに設定されます。

私が言ったように、update_only => trueを追加して修正しましたが、それでもバグだと思います。

上記の症状があなたのケースにも当てはまるかどうかを調べて、これがバグであることを確認したいと思います。

0
Victors