ネストされた属性
ネストされた属性は、単一のパラメーター ハッシュに属性をネストすることで、1 回の操作でドキュメントとその関連付けを更新するためのメカニズムを提供します。 これは、1 つのウェブ フォーム内で複数のドキュメントを編集する場合に便利です。
動作
ネストされた属性は、埋め込みまたは参照される任意の関連付けで有効にできます。 これを関連付けで有効にするには、単純に accepts_nested_attributes_for
マイクロに関連付け名を指定します。
class Band include Mongoid::Document embeds_many :albums belongs_to :producer accepts_nested_attributes_for :albums, :producer end
参照先の関連付けにネストされた属性機能を追加すると、Mongoid はその関連付けの自動保存を自動的に有効にすることに注意してください。
関連付けがネストされた属性の動作を実現すると、基本モデルに追加のメソッドが追加されます。このメソッドを使用して、新しい機能で属性を更新する必要があります。 このメソッドは、関連付け名に_attributes=
を加えたものです。 このメソッドを直接使用できますが、メソッドの名前を基本クラスのアップデートの属性にするのがより一般的です。その場合、Mongoid はカバーの下で適切なセッターを呼び出します。
band = Band.first band.producer_attributes = { name: "Flood" } band.attributes = { producer_attributes: { name: "Flood" }}
これは、 update
、 update_attributes
、 attributes=
など、Mongoid の属性ベースの setter メソッド、およびcreate
(およびこれらに対応するすべての ping メソッド)で動作することに注意してください。 たとえば、次のように、関連付けられた住所レコードを持つ新しい人の作成は、次のように 1 つのステートメントで実行できます。
person = Person.create( name: 'John Schmidt', addresses_attributes: [ { type: 'home', street: '1234 Street Ave.', city: 'Somewhere' }, { type: 'work', street: 'Parkway Blvd.', city: 'Elsewehre' }, ])
レコードの作成
_id
フィールドを省略すると、ネストされた属性を使用して新しいネストされたレコードを作成できます。
person = Person.first person.update(addresses_attributes: [ { type: 'prior', street: '221B Baker St', city: 'London' } ])
これにより、既存のセットに新しいレコードが追加されます。既存のレコードは変更されません。
レコードの更新
ネストされたレコードのいずれかに_id
フィールドを指定すると、属性を使用してその ID でレコードが更新されます。
person = Person.first address = person.addresses.first person.update(addresses_attributes: [ { _id: address._id, city: 'Lisbon' } ])
その ID を持つレコードが存在しない場合は、 Mongoid::Errors::DocumentNotFound
例外が発生することに注意してください。
レコードの破棄
この方法で特別な_destroy
属性を指定して、レコードを破棄することもできます。 これを使用するには、 accepts_nested_attributes_for
宣言とともにallow_destroy: true
を渡している必要があります。
class Person # ... accepts_nested_attributes_for :addresses, allow_destroy: true end person = Person.first address = person.addresses.first person.update(addresses_attributes: [ { _id: address._id, _destroy: true } ])
アップデートと同様に、その ID を持つレコードがない場合は、 Mongoid::Errors::DocumentNotFound
例外が発生することに注意してください。
組み合わせ操作
ネストされた属性を使用すると、1 つのステートメントでこれらのすべての操作を組み合わせることができます。 以下は、アドレスの作成、別のアドレスの更新、さらに別のアドレスの破棄を行う例です。すべてが 1 つのコマンドで行われます。
person = Person.first person.update(addresses_attributes: [ { type: 'alt', street: '1234 Somewhere St.', city: 'Cititon' }, { _id: an_address_id, city: 'Changed City' }, { _id: another_id, _destroy: true } ])