Visão geral
Neste guia, você pode aprender como definir atributos aninhados em modelos para habilitar operações de dados em documentos e suas associações. Depois de definir um atributo aninhado, você pode especificar atualizações para documentos de nível superior e associados em um único hash de parâmetro. Isso pode ser útil se seu aplicação exigir a edição de vários documentos em um único formulário.
Comportamento
Você pode habilitar atributos aninhados para qualquer associação, incorporada ou referenciada. Para adicionar um atributo aninhado para uma associação, forneça o nome da associação para a macro accepts_nested_attributes_for ao definir uma classe de modelo.
O seguinte código define associações incorporadas na classe de modelo Band e inclui a macro accepts_nested_attributes_for:
class Band include Mongoid::Document embeds_many :albums belongs_to :producer accepts_nested_attributes_for :albums, :producer end
Observação
Salvamento automático ativado
Quando você adiciona a funcionalidade de atributo aninhado a uma associação referenciada, o Mongoid ativa automaticamente o salvamento automático para essa associação.
Quando você habilita o comportamento de atributos aninhados em uma associação, o Mongoid adiciona um método especial ao modelo base. Você pode utilizar este método para atualizar os atributos.
O nome do método é o nome da associação com o sufixo _attributes. Por exemplo, o método de preparação para atualizar a associação producers é producer_attributes.
Você pode usar esse método diretamente ou pode usar o nome do método como um atributo nas atualizações da classe de nível superior. Nesse caso, o Mongoid chama o método de preparação apropriado internamente.
O código a seguir recupera uma instância de Band e, em seguida, usa o método de atualização de atributo aninhado producer_attributes para definir um valor para o documento de associação :
# Retrieves a Band instance band = Band.where(name: 'Tennis').first # Updates the "producer" association band.producer_attributes = { name: 'Alaina Moore' }
Há várias maneiras de atualizar um atributo aninhado:
Use o método de preparação
<association name>_attributes.Utilize o método de preparação
attributese especifique<association name>_attributesno valor para atualizar as associações.Utilize o método de preparação
update_attributese especifique os nomes dos atributos no valor para atualizar as associações.Utilize o método
updatee especifique<association name>_attributesno valor para atualizar as associações.Utilize o método
createe especifique<association name>_attributesno valor para criar as associações.
O exemplo a seguir demonstra como criar uma instância Band com registros album associados em uma única instrução:
band = Band.create( name: 'Tennis', albums_attributes: [ { name: 'Swimmer', year: 2020 }, { name: 'Young & Old', year: 2013 }] )
Criando documentos aninhados
Você pode criar novos documentos aninhados usando a funcionalidade atributos aninhados. Ao criar um documento, omita o campo _id. O código abaixo usa o método update para criar um documento album aninhado em uma instância Band existente:
band = Band.where(name: 'Vampire Weekend').first band.update(albums_attributes: [ { name: 'Contra', year: 2010 } ])
Essa ação anexa o novo documento ao conjunto existente sem alterar nenhum documento aninhado existente.
Atualizando documentos aninhados
Você pode atualizar documentos aninhados existentes usando a funcionalidade atributos aninhados. Para instruir o Mongoid a atualizar um documento aninhado usando atributos, passe o valor _id do documento para o método update. O exemplo seguinte utiliza o valor _id de uma entrada albums para atualizar o campo 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 } ])
Importante
NoMatchingDocument
Se o Mongoid não corresponder a um documento que tenha o valor de _id especificado, ele gerará uma exceção de Mongoid::Errors::DocumentNotFound.
Excluir documentos aninhados
Você pode excluir documentos aninhados especificando o atributo _destroy para o método update. Para habilitar a exclusão de documento aninhado, você deve definir allow_destroy: true na declaração accepts_nested_attributes_for, conforme mostrado no código a seguir:
class Band # ... accepts_nested_attributes_for :albums, allow_destroy: true end
O seguinte código utiliza o atributo _destroy para excluir a primeira entrada albums de uma instância do Band:
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 } ])
Importante
NoMatchingDocument
Se o Mongoid não corresponder a um documento que tenha o valor de _id especificado, ele gerará uma exceção de Mongoid::Errors::DocumentNotFound.
Combinar operações em documentos aninhados
Você pode executar várias operações de dados em documentos aninhados usando a funcionalidade de atributos aninhados.
O código a seguir cria um documento aninhado , atualiza um documento existente e exclui um documento na array albums de uma instância Band:
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 } ])
Informações adicionais
Para saber mais sobre queries, consulte o guia Especificar uma query de documento.
Para saber mais sobre como executar operações CRUD, consulte o guia Executar operações de dados.
Para saber mais sobre associações, consulte o guia Associações.