Associações
Nesta página
- Visão geral
- Associações referenciadas
- Tem um
- Tem muitos
- Pertence a
- Tem e pertence a muitos
- Associações referenciadas pela query
- Associações incorporadas
- Incorpora um
- Incorpora muitos
- Incorporação recursiva
- Associações incorporadas à consulta
- Omitir campos _id
- Excluir associações incorporadas
- Personalizar comportamento da associação
- Extensões
- Nomes de associação personalizados
- Chaves personalizadas
- Escopos personalizados
- Validações
- Polimorfismo
- Comportamento dependente
- Salvamento automático de associações referenciadas
- Construção automática
- Toque em
- Cache do contador
- Metadados de associação
- Atributos
Visão geral
Associações no Mongoid permitem criar relacionamentos entre modelos. Neste guia, você aprenderá sobre os diferentes tipos de associações compatíveis com o Mongoid e como usá-las em seu aplicação.
Associações referenciadas
Associações referenciadas permitem criar um relacionamento entre dois modelos em que um modelo referencia o outro. O Mongoid suporta os seguintes tipos de associação referenciados:
has_one
has_many
belongs_to
has_and_belongs_to_many
As seções a seguir descrevem como usar cada um desses tipos de associação.
Tem um
Você pode usar a macro has_one
para declarar que os documentos representados por uma classe também contêm um documento representado por uma classe filha separada. O exemplo seguinte cria uma classe Band
com um relacionamento has_one
com uma classe Studio
:
class Band include Mongoid::Document has_one :studio end
Quando você declara uma associação has_one
, a classe filha também deve usar a associação belongs_to
que referencia a classe pai. O exemplo seguinte mostra a classe Studio
referenciada na classe Band
anterior:
class Studio include Mongoid::Document belongs_to :band end
Para saber mais sobre a belongs_to
macro, consulte a seção Pertence a.
Você pode usar validações para garantir que a classe filho esteja presente em sua classe pai, conforme mostrado no exemplo a seguir:
class Band include Mongoid::Document has_one :studio validates_presence_of :studio end
Para saber mais sobre validações no Mongoid, consulte o guia deValidações do.
Tem muitos
Você pode usar a macro has_many
para declarar que os documentos representados por uma classe contêm vários documentos filhos representados por outra classe. O exemplo seguinte cria uma classe Band
com um relacionamento has_many
com uma classe Members
:
class Band include Mongoid::Document has_many :members end
Quando você declara uma associação has_many
, a classe filha também deve usar a associação belongs_to
que referencia a classe pai. O exemplo seguinte mostra a classe Member
referenciada na classe Band
anterior:
class Member include Mongoid::Document belongs_to :band end
Para saber mais sobre a belongs_to
macro, consulte a seção Pertence a.
Você pode usar validações para garantir que a classe filho esteja presente em sua classe pai, conforme mostrado no exemplo a seguir:
class Band include Mongoid::Document has_many :members validates_presence_of :members end
Para saber mais sobre validações no Mongoid, consulte o guia Validações.
Recuperar informações de associação
Você pode usar o método any?
em uma associação has_many
para determinar se a associação contém algum documento sem recuperar todo o conjunto de documentos do banco de dados.
O exemplo seguinte utiliza o método any?
para determinar se documentos na classe Band
contêm quaisquer documentos Members
:
band = Band.first band.members.any?
Você também pode usar o método any?
com um filtro para localizar documentos que correspondam a um critério especificado, conforme mostrado no exemplo a seguir:
band = Band.first band.members.any? { |member| member.instrument == 'piano' }
Você pode fornecer um nome de classe para o método any?
para filtrar os resultados pelo nome da classe. Isso é útil para associações polimórficas:
class Drummer < Member end band = Band.first band.members.any?(Drummer)
Observação
Depois que os dados da classe associada são carregados no Mongoid, as chamadas subsequentes para o método any?
não fazem query no banco de dados. Em vez disso, o Mongoid usa os dados que já estão carregados na memória.
Você também pode chamar o método exists?
para determinar se há algum documento persistente na associação. O método exists?
sempre consulta o banco de dados e verifica somente documentos que foram salvos no banco de dados. O método exists?
não permite a filtragem e não aceita nenhum argumento.
O exemplo seguinte utiliza o método exists?
para determinar se há algum documento Members
persistente na classe Band
:
band = Band.create! # Member is not persisted. band.members.build band.members.exists? # Outputs: false # Persist the member band.members.map(&:save!) band.members.exists? # Outputs: true
Pertence a
Use a macro belongs_to
para declarar que um documento representado por uma classe é filho de um documento representado por outra classe. Por padrão, o campo _id
da classe pai é armazenado na classe filho. O exemplo seguinte cria uma classe Members
com uma associação belongs_to
para uma classe Band
:
class Members include Mongoid::Document belongs_to :band end
Você pode permitir que o Mongoid persista documentos no banco de dados sem armazenar o _id
da classe pai associada definindo a opção optional
como true
, conforme mostrado no exemplo a seguir:
class Members include Mongoid::Document belongs_to :band, optional: true end
Dica
Você pode alterar globalmente o comportamento padrão da associação belongs_to
para não exigir sua classe pai definindo a opção de configuração belongs_to_required_by_default
como false
nas definições de configuração do seu aplicativo.
Você pode especificar uma associação belongs_to
em uma classe filha sem especificar uma associação has_one
ou has_many
correspondente na classe pai. Ao fazer isso, você não pode acessar os campos do documento filho a partir da classe pai, mas pode acessar os campos pai que estão armazenados na classe filho, como o campo _id
do pai. No exemplo a seguir , a classe Band
não pode acessar a classe Members
, mas a classe Members
pode acessar a classe Band
:
class Band include Mongoid::Document end class Members include Mongoid::Document belongs_to :band end
Para maior clareza, você pode opcionalmente definir a opção inverse_of
como nil
para indicar que a classe principal não contém uma associação has_one
ou has_many
com a classe secundária, conforme mostrado no exemplo a seguir:
class Band include Mongoid::Document end class Members include Mongoid::Document belongs_to :band, inverse_of: nil end
Tem e pertence a muitos
Use a macro has_and_belongs_to_many
para declarar que um modelo de classe contém uma relacionamento de muitos para muitos com outra classe. Em um relacionamento de muitos para muitos , cada documento em uma classe pode ser associado a vários documentos em outra classe. O exemplo seguinte cria uma classe Band
com um relacionamento has_and_belongs_to_many
com uma classe Members
. Um documento Band
pode fazer referência a vários documentos Members
e um documento Members
pode fazer referência a vários documentos Band
.
class Band include Mongoid::Document has_and_belongs_to_many :members end class Members include Mongoid::Document has_and_belongs_to_many :bands end
Quando você declara uma associação has_and_belongs_to_many
, ambas as instâncias do modelo armazenam uma lista dos valores _id
do documento associado. Você pode definir a opção inverse_of
como nil
para armazenar os valores _id
do documento associado em apenas uma das instâncias do modelo. O exemplo a seguir solicita que o Mongoid armazene os valores _id
do documento associado apenas na classe Band
:
class Band include Mongoid::Document has_and_belongs_to_many :tags, inverse_of: nil end class Tag include Mongoid::Document end
Dica
Quando você atualiza um documento que tenha uma associação has_and_belongs_to_many
, o Mongoid define o campo updated_at
do documento atualizado, mas não define o campo updated_at
dos documentos associados.
Associações referenciadas pela query
Você pode usar um pipeline de agregação para consultar documentos em associações referenciadas. O pipeline de agregação permite criar queries em várias coleções e manipular dados em um formato especificado. Para saber mais sobre como usar o pipeline de agregação , consulte o Guia de agregação.
Para queries simples, você pode consultar a associação diretamente. Ao consultar diretamente uma coleção, você pode consultar apenas em campos e valores que estão na própria coleção. Você não pode fazer query diretamente de collections associadas à que está consultando.
Por exemplo, considere as seguintes classes Band
e Tour
:
class Band include Mongoid::Document has_many :tours field :name, type: String end class Tour include Mongoid::Document belongs_to :band field :year, type: Integer end
O exemplo a seguir faz uma query da classe Tour
para documentos que têm um valor year
de 2000
ou superior e salva o band_id
desses documentos. Em seguida, ele faz uma query da classe Band
para documentos que tenham esses valores band_id
.
band_ids = Tour.where(year: {'$gte' => 2000}).pluck(:band_id) bands = Band.find(band_ids)
Associações incorporadas
Você pode usar associações incorporadas para armazenar diferentes tipos de documentos na mesma coleção. O Mongoid suporta associações incorporadas com as seguintes macros:
embeds_one
embeds_many
embedded_in
recursively_embeds_one
recursively_embeds_many
As seções a seguir descrevem como usar esses tipos de associação.
Incorpora um
Para especificar que um modelo de classe contém um documento incorporado de um tipo de classe diferente, use a macro embeds_one
na classe principal e a macro embedded_in
na classe incorporada. O exemplo a seguir cria uma classe Band
com uma classe Label
incorporada :
class Band include Mongoid::Document embeds_one :label end class Label include Mongoid::Document field :name, type: String embedded_in :band end
O Mongoid armazena documentos incorporados com a macro embeds_one
no documento principal como um campo com o mesmo nome da classe incorporada. Os documentos Label
anteriores são armazenados no documento Band
, conforme mostrado no exemplo a seguir:
# Band document { "_id" : ObjectId("..."), "label" : { "_id" : ObjectId("..."), "name" : "Periphery", } }
Você pode armazenar o documento incorporado com um nome diferente usando a opção store_as
, conforme mostrado no exemplo a seguir:
class Band include Mongoid::Document embeds_one :label, store_as: "record_label" end
Incorpora muitos
Para especificar que um modelo de classe contém vários documentos incorporados de um tipo de classe diferente, use a macro embeds_many
na classe principal e a macro embedded_in
na classe incorporada. O exemplo a seguir cria uma classe Band
com vários documentos do tipo Album
incorporados:
class Band include Mongoid::Document embeds_many :albums end class Album include Mongoid::Document field :name, type: String embedded_in :band end
O Mongoid armazena documentos incorporados com a macro embeds_many
no documento principal como um campo de array com o mesmo nome da classe incorporada. Os documentos Album
anteriores são armazenados no documento Band
, conforme mostrado no exemplo a seguir:
{ "_id" : ObjectId("..."), "albums" : [ { "_id" : ObjectId("..."), "name" : "Omega", } ] }
Você pode armazenar o documento incorporado com um nome diferente usando a opção store_as
, conforme mostrado no exemplo a seguir:
class Band include Mongoid::Document embeds_many :albums, store_as: "records" end
Incorporação recursiva
Você pode incorporar um ou mais documentos do mesmo tipo em uma classe principal usando as macros recursively_embeds_one
e recursively_embeds_many
. Ambas as macros fornecem acessadores para os documentos pai e filho por meio de um método parent_*
e um método child_*
, em que *
representa o nome da classe. O exemplo a seguir cria uma classe Band
que incorpora recursivamente vários outros documentos Band
para representar vários nomes de bandas:
class Band include Mongoid::Document field :name, type: String recursively_embeds_many end
Você pode acessar os documentos principal e secundário por meio dos métodos parent_band
e child_band
, conforme mostrado no exemplo a seguir:
root = Band.new(name: "Linkin Park") # Add child bands child_one = root.child_band.build(name: "Lincoln Park") child_two = root.child_band.build(name: "Xero") # Access parent band child_one.parent_band # Outputs: root
Associações incorporadas à consulta
Você pode acessar documentos incorporados ao consultar a collection da classe principal usando a notação de ponto.
O exemplo a seguir usa notação de ponto para consultar documentos do tipo Tour
que estão incorporados em uma classe Band
. A query retorna documentos com um valor tours.year
de 2000
ou superior:
Band.where('tours.year' => {'$gte' => 2000})
Você pode usar o método de projeção pluck
para recuperar documentos incorporados sem recuperar seus documentos pai associados, conforme mostrado no exemplo a seguir:
# Get awards for bands that have toured since 2000 Band.where('tours.year' => {'$gte' => 2000}).pluck(:awards)
Você pode usar os métodos de query do Mongoid para realizar a correspondência incorporada, o que permite consultar associações incorporadas de documentos que já estão carregados no aplicação. O Mongoid implementa a correspondência incorporada sem enviar queries para o servidor.
Os seguintes operadores de query são compatíveis com correspondência incorporada:
O exemplo a seguir consulta o campo tours
incorporado de um documento Band
carregado usando o operador de comparação $gte
:
band = Band.where(name: 'Astral Projection').first tours = band.tours.where(year: {'$gte' => 2000})
A correspondência incorporada em documentos carregados tem as seguintes limitações conhecidas:
A correspondência incorporada não está implementada para as seguintes funcionalidades:
Operadores que executam código JavaScript, como $where
Operadores implementados por meio de outras funcionalidades do servidor , como $expr e $jsonSchema
O Mongoid expande os argumentos
Range
para hashes com condições$gte
e$lte
. Isso pode levar a queries inválidas em alguns casos e gera uma exceçãoInvalidQuery
.Com o operador
$regex
, você não pode especificar um objeto de expressão regular como um padrão e, ao mesmo tempo, fornecer opções para o campo$options
. Você só pode fornecer opções se o padrão de expressão regular for uma string.As versões 4.0 e anteriores do MongoDB Server não validam estritamente os argumentos
$type
.
Omitir campos _id
Por padrão, o Mongoid adiciona um campo _id
aos documentos incorporados. Você pode omitir esse campo de documentos incorporados especificando explicitamente o campo _id
em seu modelo e omitindo o valor padrão. O exemplo a seguir instrui o Mongoid a não adicionar um campo _id
à classe Albums
:
class Album include Mongoid::Document field :name, type: String field :_id, type: Object embedded_in :band end
Na classe Albums
anterior, o campo _id
não é adicionado automaticamente. Sem um valor padrão, o Mongoid não armazena o valor no banco de dados, a menos que você forneça um em seu modelo.
Excluir associações incorporadas
Você pode excluir documentos filhos de associações embeds_many
usando um dos seguintes métodos:
clear
delete_all
destroy_all
O clear
método utiliza o operador operador $unset para remover uma associação incorporada inteira do documento principal. O método clear
não executa nenhuma chamada de resposta destroy
. O exemplo a seguir usa o método clear
para remover todas as associações incorporadas da classe Band
:
band = Band.find(...) band.tours.clear
O delete_all
método utiliza o operador operador $pullAll para remover documentos em uma associação incorporada. delete_all
carrega a associação se ela ainda não tiver sido carregada e remove apenas os documentos existentes no aplicação. O método delete_all
não executa nenhuma chamada de resposta destroy
. O exemplo a seguir usa o método delete_all
para remover todos os documentos Album
incorporados da classe Band
:
band = Band.find(...) band.tours.delete_all
O destroy_all
método também usa o operador $pullAll para remover documentos em uma associação incorporada. Ele também executa quaisquer chamada de resposta destroy
definidas nos documentos associados. O exemplo a seguir usa o método destroy_all
para remover todos os documentos Album
incorporados da classe Band
:
band = Band.find(...) band.tours.destroy_all
Personalizar comportamento da associação
Você pode usar o Mongoid para personalizar como as associações se comportam em seu aplicação. As seções a seguir descrevem maneiras de personalizar comportamentos de associação.
Extensões
As extensões permitem adicionar funcionalidade personalizada a uma associação. Você pode definir uma extensão em uma associação especificando um bloco na definição da associação, conforme mostrado no exemplo a seguir:
class Band include Mongoid::Document embeds_many :albums do def find_by_name(name) where(name: name).first end end end band.albums.find_by_name("Omega") # returns album "Omega"
Nomes de associação personalizados
Você pode usar a macro class_name
para especificar um nome de classe personalizado para uma associação. Isto é útil quando você deseja nomear a associação com algo diferente do nome da classe. O exemplo a seguir usa a macro class_name
para especificar que uma associação embutida chamada records
representa a classe Album
:
class Band include Mongoid::Document embeds_many :records, class_name: "Album" end
Chaves personalizadas
Por padrão, o Mongoid usa o campo _id
da classe pai ao procurar associações. Você pode especificar campos diferentes para utilizar utilizando as macros primary_key
e foreign_key
. O exemplo a seguir especifica uma nova chave primária e externa para a associação albums
em uma classe Band
:
class Band include Mongoid::Document field :band_id, type: String has_many :albums, primary_key: 'band_id', foreign_key: 'band_id_ref' end class Album include Mongoid::Document field :band_id_ref, type: String belongs_to :band, primary_key: 'band_id', foreign_key: 'band_id_ref' end
Se você estiver especificando uma associação has_and_belongs_to_many
, também poderá usar as macros inverse_primary_key
e inverse_foreign_key
. A macro inverse_primary_key
especifica o campo no modelo local que o modelo remoto utiliza para procurar os documentos. A macro inverse_foreign_key
especifica o campo no modelo remoto que armazena os valores encontrados no inverse_primary_key
.
O exemplo a seguir especifica uma nova chave primária e externa para as classes Band
e Members
em uma associação has_and_belongs_to_many
:
class Band include Mongoid::Document field :band_id, type: String field :member_ids, type: Array has_many :members, primary_key: 'member_id', foreign_key: 'member_ids', inverse_primary_key: 'band_id', inverse_foreign_key: 'band_ids' end class Member include Mongoid::Document field :member_id, type: String field :band_ids, type: Array has_many :bands, primary_key: 'band_id', foreign_key: 'band_ids', inverse_primary_key: 'member_id', inverse_foreign_key: 'member_ids' end
Escopos personalizados
Você pode especificar o escopo de uma associação usando o parâmetro scope
. O parâmetro scope
determina os documentos que o Mongoid considera parte de uma associação. Uma associação com escopo gera apenas documentos que correspondem às condições do escopo quando consultadas. Você pode configurar o scope
para um Proc
com uma aridade de zero ou um Symbol
que faz referência a um escopo nomeado no modelo associado. O exemplo a seguir define escopos personalizados em associações em uma classe Band
:
class Band include Mongoid::Document has_many :albums, scope: -> { where(published: true) } # Uses a scope called "upcoming" on the Tour model has_many :tours, scope: :upcoming end
Observação
Você pode adicionar documentos que não correspondem às condições de escopo a uma associação. O Mongoid salva os documentos no banco de dados e eles aparecerão na memória associada. No entanto, você não verá os documentos ao consultar a associação.
Validações
Quando o Mongoid carrega uma associação na memória, por padrão, ele usa a macro validates_associated
para validar que quaisquer filhos também estão presentes. O Mongoid valida crianças para os seguintes tipos de associação:
embeds_many
embeds_one
has_many
has_one
has_and_belongs_to_many
Você pode desativar esse comportamento de validação definindo a macro validate
como false
ao definir a associação, conforme mostrado no exemplo a seguir:
class Band include Mongoid::Document embeds_many :albums, validate: false end
Polimorfismo
O Mongoid suporta o polimorfismo nas classes filhos de associações um-para-um e um-para-muitos. Associações polimórficas permitem que uma única associação contenha objetos de diferentes tipos de classe . Você pode definir uma associação polimórfica definindo a opção polymorphic
como true
em uma associação filho e adicionando a opção as
à associação pai. O exemplo seguinte cria uma associação polimórfica em uma classe Band
:
class Tour include Mongoid::Document has_one :band, as: :featured end class Label include Mongoid::Document has_one :band, as: :featured end class Band include Mongoid::Document belongs_to :featured, polymorphic: true end
No exemplo anterior, a associação :featured
na classe Band
pode conter um documento Label
ou Album
.
Importante
O Mongoid suporta o polimorfismo apenas de filho para pai. Você não pode especificar uma associação pai has_one
ou has_many
como polimórfica.
has_and_belongs_to_many
associações não apoiam polimorfismo.
Tipos polimórficos personalizados
A partir da versão 9.0.2, O Mongoid suporta tipos polimórficos personalizados por meio de um registro global. Você pode especificar chaves alternativas para representar classes diferentes, desacoplar seu código dos dados. O exemplo a seguir especifica a string "artist"
como uma chave alternativa para a classe Band
:
class Band include Mongoid::Document identify_as 'artist' has_many :albums, as: :record end
No exemplo anterior, a diretiva identify_as
instrui o Mongoid a armazenar a classe Band
no banco de dados como a string "artist"
.
Você também pode especificar vários aliases, como mostrado no exemplo a seguir:
class Band include Mongoid::Document identify_as 'artist', 'group', 'troupe' has_many :albums, as: :record end
No exemplo anterior, artist
é o nome padrão e os outros são usados somente para procurar registros. Isso permite que você refatore seu código sem quebrar as associações em seus dados.
Os aliases de tipo polimórfico são globais. As chaves especificadas devem ser exclusivas em toda a sua base de código. No entanto, você pode registrar resolvedores alternativos que podem ser usados para diferentes subconjuntos de seus modelos. Nesse caso, as chaves devem ser exclusivas apenas para cada resolvedor. O exemplo a seguir mostra como registrar resolvedores alternativos:
Mongoid::ModelResolver.register_resolver Mongoid::ModelResolver.new, :mus Mongoid::ModelResolver.register_resolver Mongoid::ModelResolver.new, :tool module Music class Band include Mongoid::Document identify_as 'bnd', resolver: :mus end end module Tools class Band include Mongoid::Document identify_as 'bnd', resolver: :tool end end
Tanto Music::Band
quanto Tools::Band
têm nomes alternativos "bnd"
, mas cada modelo usa seu próprio resolvedor para evitar conflitos.
Comportamento dependente
Você pode fornecer opções dependent
às associações referenciadas para especificar como o Mongoid lida com documentos associados quando um documento é excluído. Você pode especificar as seguintes opções:
delete_all
: Exclui todos os documentos filhos sem executar nenhum retorno de chamada de resposta.destroy
: Exclui os documentos filhos e executa todos os retornos de chamada do modelo.nullify
: define a chave estrangeira dos documentos filhos comonil
. O documento filho pode se tornar órfão se for referenciado apenas pelo pai.restrict_with_exception
: Gera uma exceção se o documento filho não estiver vazio.restrict_with_error
: cancela a operação e retornafalse
se o documento filho não estiver vazio.
Se você não especificar nenhuma opção dependent
, o Mongoid deixará o documento filho inalterado quando o documento pai for excluído. O documento filho continua a fazer referência ao documento pai excluído e, se for referenciado apenas pelo pai, o documento filho ficará órfão.
O exemplo seguinte especifica dependent
opções na classe Band
:
class Band include Mongoid::Document has_many :albums, dependent: :delete_all belongs_to :label, dependent: :nullify end
Salvamento automático de associações referenciadas
Por padrão, o Mongoid não salva automaticamente os documentos associados de associações não incorporadas ao salvar o documento pai. Isso pode resultar em referências pendentes a documentos que não existem.
Você pode usar a opção autosave
em uma associação referenciada para salvar automaticamente os documentos associados ao salvar o documento pai. O exemplo seguinte cria uma classe Band
com uma classe Album
associada e especifica a opção autosave
:
class Band include Mongoid::Document has_many :albums end class Album include Mongoid::Document belongs_to :band, autosave: true end band = Band.new album = Album.create!(band: band) # The band is persisted at this point.
Observação
O Mongoid adiciona automaticamente a funcionalidade de salvamento automático a uma associação que usa a opção accepts_nested_attributes_for
.
Você não precisa especificar a opção autosave
para associações incorporadas porque o Mongoid salva documentos incorporados no documento pai.
Construção automática
Você pode adicionar a opção autobuild
a associações um-para-um, como has_one
e embeds_one
, para instanciar automaticamente um novo documento ao acessar uma associação nil
. O exemplo a seguir adiciona a opção autobuild
a uma associação na classe Band
:
class Band include Mongoid::Document embeds_one :label, autobuild: true has_one :producer, autobuild: true end
Toque em
Quando o Mongoid toca um documento, ele atualiza o campo do documento updated_at
para a data e hora atuais. Você pode adicionar a opção touch
a qualquer associação belongs_to
para garantir que o Mongoid toque no documento pai sempre que o documento filho for atualizado. O exemplo a seguir adiciona a opção touch
a uma associação na classe Band
:
class Band include Mongoid::Document field :name belongs_to :label, touch: true end
Você também pode utilizar a opção touch
para especificar outro campo na associação pai, como uma string ou um símbolo. Quando o Mongoid toca a associação pai, ele define o campo updated_at
e o campo especificado para a data e hora atuais.
O exemplo a seguir instrui o Mongoid a tocar no campo bands_updated_at
:
class Band include Mongoid::Document belongs_to :label, touch: :bands_updated_at end
Observação
Em associações incorporadas, quando um documento incorporado é tocado, o Mongoid afeta seus pais recursivamente. Por esse motivo, adicionar um atributo touch
a uma associação embedded_in
é desnecessário.
O Mongoid não suporta a especificação de campos adicionais para tocar em embedded_in
associações.
Cache do contador
Você pode utilizar a opção counter_cache
para armazenar o número de objetos que pertencem a um campo associado. Quando você especifica esta opção, o Mongoid armazena um atributo extra nos modelos associados para armazenar a contagem. Por esse motivo, você deve especificar o módulo Mongoid::Attributes::Dynamic
nas classes associadas.
O exemplo seguinte adiciona a opção counter_cache
a uma classe Band
e especifica o Mongoid::Attributes::Dynamic
em uma classe Label
:
class Band include Mongoid::Document belongs_to :label, counter_cache: true end class Label include Mongoid::Document include Mongoid::Attributes::Dynamic has_many :bands end
Metadados de associação
Quando você define uma associação, o Mongoid armazena metadados sobre essa associação. Você pode acessar os metadados chamando o método reflect_on_association
em uma classe de modelo ou documento ou acessando diretamente os metadados em um documento específico. O exemplo a seguir mostra como acessar metadados usando o método reflect_on_association
e por acesso direto:
# Get the metadata for a named association from the class or document Model.reflect_on_association(:<association_name>) # Directly access metadata on a document model.associations[:<association_name>]
Observação
Substitua <association_name>
no exemplo anterior pelo nome da sua associação.
Atributos
Todas as associações contêm atributos que armazenam informações sobre o documento associado. As associações contêm os seguintes atributos:
_target
: O documento ou documentos procurados_base
: O documento no qual a associação está definida_association
: Informações sobre a associação
O exemplo a seguir acessa cada um dos atributos anteriores:
class Band include Mongoid::Document embeds_many :songs end Band.songs = [ song ] Band.songs._target # returns [ song ] Band.songs._base # returns band Band.songs._association # returns the association metadata
A tabela seguinte mostra as informações armazenadas no atributo _association
:
Método | Descrição |
---|---|
| O nome do pai para um filho polimórfico. |
| Retorna se existe uma opção |
| Retorna se a associação é de construção automática. |
| Retorna se a associação está salvando automaticamente. |
| Retorna se a associação tem retornos de chamada em cascata do pai. |
| O nome da classe do documento com proxy. |
| Retorna se a associação é uma associação cíclica. |
| A opção dependente da associação. |
| Retorna |
| Retorna se a associação está incorporada em outro documento. |
| Retorna se a associação tem um |
| O nome do campo de chave estrangeira. |
| O nome do método de verificação suja do campo de chave estrangeira. |
| O nome do configurador do campo de chave estrangeira. |
| Retorna se a chave estrangeira é indexada automaticamente. |
| Os nomes de todas as associações inversas. |
| O nome de uma única associação inversa. |
| O nome da classe da associação no lado inverso. |
| O nome do campo de chave estrangeira no lado inverso. |
| A classe da associação no lado inverso. |
| Os metadados da associação no lado inverso. |
| O nome explicitamente definido da associação inversa. |
| O nome do método usado para definir a inversa. |
| O nome do campo do tipo polimórfico do inverso. |
| O nome do set do campo do tipo polimórfico do inverso. |
| O nome do campo no hash do atributo que é usado para obter a associação. |
| A classe dos documentos com proxy na associação. |
| O nome da associação. |
| Retorna |
| As opções de classificação personalizada na associação. |
| Retorna se a associação é polimórfica. |
| O nome do campo para definir a associação. |
| O nome do atributo no qual armazenar uma associação embarcada. |
| Retorna se a associação tem uma opção de toque. |
| O nome do campo para obter o tipo polimórfico. |
| O nome do campo para definir o tipo polimórfico. |
| Retorna se a associação tem uma validação associada. |