Atributos aninhados
Nesta página
Os atributos aninhados fornecem um mecanismo para atualizar documentos e suas associações em uma única operação, aninhando atributos em um único hash de parâmetros. Isso é útil para editar vários documentos em um único formulário da Web.
Comportamento
Atributos aninhados podem ser habilitados para qualquer associação, incorporado ou referenciado. Para habilitar isso para uma associação, basta fornecer o nome da associação para a macro accepts_nested_attributes_for
.
class Band include Mongoid::Document embeds_many :albums belongs_to :producer accepts_nested_attributes_for :albums, :producer end
Observe que, quando você adiciona a funcionalidade de atributos aninhados a uma associação referenciada, o Mongoid ativará automaticamente o salvamento automático para essa associação.
Quando uma associação obtém o comportamento de atributos aninhados, um método adicional é adicionado ao modelo base, que deve ser usado para atualizar os atributos com a nova funcionalidade. Este método é o nome da associação mais _attributes=
. Você pode usar esse método diretamente ou, mais comumente, o nome do método pode ser um atributo nas atualizações da classe base , caso em que o Mongoid chamará o setter apropriado sob as cobertas.
band = Band.first band.producer_attributes = { name: "Flood" } band.attributes = { producer_attributes: { name: "Flood" }}
Observe que isso funcionará com qualquer método de setter baseado em atributo no Mongoid, incluindo update
, update_attributes
e attributes=
, bem como create
(e todos os seus métodos bingo correspondentes). Por exemplo, criar uma nova pessoa com registros de endereço associados pode ser feito em uma única instrução, como esta:
person = Person.create( name: 'John Schmidt', addresses_attributes: [ { type: 'home', street: '1234 Street Ave.', city: 'Somewhere' }, { type: 'work', street: 'Parkway Blvd.', city: 'Elsewehre' }, ])
Criação de registros
Você pode criar novos registros aninhados por meio de atributos aninhados omitindo um campo _id
:
person = Person.first person.update(addresses_attributes: [ { type: 'prior', street: '221B Baker St', city: 'London' } ])
Isso anexará o novo registro ao conjunto existente; os registros existentes não serão alterados.
Atualizando registros
Se você especificar um campo _id
para qualquer um dos registros aninhados, os atributos serão utilizados para atualizar o registro com esse ID:
person = Person.first address = person.addresses.first person.update(addresses_attributes: [ { _id: address._id, city: 'Lisbon' } ])
Observe que, se não houver nenhum registro com esse ID, uma exceção Mongoid::Errors::DocumentNotFound
será gerada.
Destruindo registros
Você também pode destruir registros dessa forma, especificando um atributo especial do _destroy
. Para usar isso, você deve ter passado allow_destroy: true
com a declaração 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 } ])
Observe que, como nas atualizações, se não houver nenhum registro com esse ID, uma exceção Mongoid::Errors::DocumentNotFound
será gerada.
Combinando operações
Os atributos aninhados permitem combinar todas essas operações em uma única declaração! Aqui está um exemplo que cria um endereço, atualiza outro endereço e destrói mais um endereço, tudo em um único comando:
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 } ])