嵌套属性
Overview
在本指南中,您可以学习;了解如何在模型上定义嵌套属性,以便对文档及其关联启用数据操作。定义嵌套属性后,您可以在单个参数哈希中指定对顶级文档和关联文档的更新。 如果您的应用程序需要编辑单个表单中的多个文档,这可能很有用。
行为
您可以为任何关联(嵌入的或引用的)启用嵌套属性。 要为关联添加嵌套属性,请在定义模型类时向 accepts_nested_attributes_for
宏提供关联名称。
以下代码在 Band
模型类上定义嵌入式关联,并包含 accepts_nested_attributes_for
宏:
class Band include Mongoid::Document embeds_many :albums belongs_to :producer accepts_nested_attributes_for :albums, :producer end
注意
自动保存已启用
当您将嵌套属性功能添加到引用的关联时,Mongoid 会自动为该关联启用自动保存。
当您在关联上启用嵌套属性行为时,Mongoid 会向基本模型添加一个特殊方法。 您可以使用此方法来更新属性。
方法名称是以 _attributes
为后缀的关联名称。 示例,更新producers
关联的 setter 方法是 producer_attributes
。
您可以直接使用此方法,也可以在顶级类的更新中将该方法的名称用作属性。 在这种情况下,Mongoid 在内部调用适当的 setter 方法。
以下代码检索 Band
的实例,然后使用嵌套属性更新方法 producer_attributes
为关联文档设立值:
# Retrieves a Band instance band = Band.where(name: 'Tennis').first # Updates the "producer" association band.producer_attributes = { name: 'Alaina Moore' }
更新嵌套属性的方法有多种:
使用
<association name>_attributes
setter 方法。使用
attributes
setter 方法并在值中指定<association name>_attributes
以更新关联。使用
update_attributes
setter 方法并指定值中的属性名称以更新关联。使用
update
方法并在值中指定<association name>_attributes
以更新关联。使用
create
方法并在值中指定<association name>_attributes
以创建关联。
以下示例演示了如何在单个声明中创建具有关联 album
记录的 Band
实例:
band = Band.create( name: 'Tennis', albums_attributes: [ { name: 'Swimmer', year: 2020 }, { name: 'Young & Old', year: 2013 }] )
创建嵌套文档
您可以使用嵌套属性功能创建新的嵌套文档。 创建文档时,请省略 _id
字段。 以下代码使用 update
方法在现有 Band
实例上创建嵌套的 album
文档:
band = Band.where(name: 'Vampire Weekend').first band.update(albums_attributes: [ { name: 'Contra', year: 2010 } ])
此动作会将新文档追加到现有文档设立,而不更改任何现有的嵌套文档。
更新嵌套文档
您可以使用嵌套属性功能更新现有的嵌套文档。 要指示 Mongoid 使用属性更新嵌套文档,请将文档的 _id
值传递给 update
方法。 以下示例使用 albums
条目的 _id
值来更新year
字段:
band = Band.where(name: 'Vampire Weekend').first # Retrieves the first entry from the albums array album = band.albums.first # Updates the entry by passing the _id value band.update(albums_attributes: [ { _id: album._id, year: 2011 } ])
重要
NoMatchingDocument
如果 Mongoid 与具有指定 _id
值的文档不匹配,则会引发 Mongoid::Errors::DocumentNotFound
异常。
删除嵌套文档
您可以通过为 update
方法指定 _destroy
属性来删除嵌套文档。 要启用嵌套文档的删除,您必须在 accepts_nested_attributes_for
声明中设立allow_destroy: true
,如以下代码所示:
class Band # ... accepts_nested_attributes_for :albums, allow_destroy: true end
以下代码使用 _destroy
属性删除Band
实例的第一个 albums
条目:
band = Band.where(name: 'Vampire Weekend').first # Retrieves the first entry from the albums array album = band.albums.first # Deletes the entry by passing the _id value band.update(albums_attributes: [ { _id: album._id, _destroy: true } ])
重要
NoMatchingDocument
如果 Mongoid 与具有指定 _id
值的文档不匹配,则会引发 Mongoid::Errors::DocumentNotFound
异常。
对嵌套文档进行组合操作
您可以使用嵌套属性功能对嵌套文档执行多个数据操作。
以下代码创建一个嵌套文档,更新现有文档,并删除 Band
实例的 albums
大量中的文档:
band = Band.where(name: 'Yeah Yeah Yeahs').first # Performs multiple data changes band.update(albums_attributes: [ { name: 'Show Your Bones', year: 2006 }, { _id: 1, name: 'Fever To T3ll' }, { _id: 2, _destroy: true } ])
更多信息
要学习;了解有关查询的更多信息,请参阅《指定文档查询》指南。