Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Menu Docs
Página inicial do Docs
/ /

Associações referenciadas

Associações no Mongoid permitem criar relacionamentos entre modelos. Neste guia, você pode aprender como associações referenciadas permitem criar um relacionamento entre dois modelos em que um modelo faz referência ao 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.

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.

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.

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

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

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.

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)

Voltar

Chamadas de resposta

Nesta página