嵌套属性
嵌套属性提供了一种通过在单个参数哈希中嵌套属性在单个操作中更新文档及其关联的机制。 当想要在单个 Web 表单中编辑多个文档时,这非常有用。
行为
可以为任何关联(嵌入式关联或引用关联)启用嵌套属性。 要为关联启用此功能,只需向 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 将在幕后调用适当的 setter。
band = Band.first band.producer_attributes = { name: "Flood" } band.attributes = { producer_attributes: { name: "Flood" }}
请注意,这适用于 Mongoid 中任何基于属性的 setter 方法,包括update
、 update_attributes
和attributes=
以及create
(及其所有相应的 bang 方法)。 例如,可以在单个语句中创建具有关联地址记录的新人员,如下所示:
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
属性,以这种方式销毁记录。 要使用此功能,您必须传递带有allow_destroy: true
accepts_nested_attributes_for
声明的 :
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
异常。
组合操作
嵌套属性允许您将所有这些操作组合在一条语句中! 以下示例创建了一个地址、更新了另一个地址并销毁了另一个地址,所有这一切都通过一条命令完成:
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 } ])