嵌套属性
嵌套属性提供了一种机制,通过在一个参数哈希中嵌套属性,在单个操作中更新文档及其关联。当想要在单个网页表单中编辑多个文档时,这很有用。
行为
可以针对任何关联(嵌套或引用)启用嵌套属性。要为关联启用此功能,只需将关联名称提供给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" }}
请注意,这将在 Mongoid 的任何基于属性的设置方法中工作,包括 update
、update_attributes
和 attributes=
,以及 create
(以及所有相应的叹号方法)。例如,可以通过单个语句创建一个新的具有关联地址记录的人,如下所示
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
异常。
组合操作
嵌套属性允许您在单个语句中组合所有这些操作!以下是一个示例,它创建了一个地址,更新了另一个地址,并销毁了一个地址,所有这些都在一个命令中完成
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 } ])