O Mongoid não tem has_many: through ou um recurso equivalente. Não seria tão útil com o MongoDB porque não oferece suporte a consultas de junção, portanto, mesmo que você pudesse fazer referência a uma coleção relacionada por meio de outra, ainda assim exigiria várias consultas.
https://github.com/mongoid/mongoid/issues/544
Normalmente, se você tiver um relacionamento muitos-muitos em um RDBMS, você modelaria isso de forma diferente no MongoDB usando um campo contendo um array de chaves 'estrangeiras' em cada lado. Por exemplo:
class Physician
include Mongoid::Document
has_and_belongs_to_many :patients
end
class Patient
include Mongoid::Document
has_and_belongs_to_many :physicians
end
Em outras palavras, você eliminaria a tabela de junção e teria um efeito semelhante a has_many: through em termos de acesso ao 'outro lado'. Mas, no seu caso, isso provavelmente não é apropriado porque sua tabela de junção é uma classe Appointment que carrega algumas informações extras, não apenas a associação.
Como você modela isso depende, em certa medida, das consultas que você precisa executar, mas parece que você precisará adicionar o modelo de consulta e definir associações para paciente e médico da seguinte forma:
class Physician
include Mongoid::Document
has_many :appointments
end
class Appointment
include Mongoid::Document
belongs_to :physician
belongs_to :patient
end
class Patient
include Mongoid::Document
has_many :appointments
end
Com relacionamentos no MongoDB, você sempre precisa fazer uma escolha entre documentos incorporados ou associados. Em seu modelo, acho que MeetingNotes é um bom candidato para um relacionamento integrado.
class Appointment
include Mongoid::Document
embeds_many :meeting_notes
end
class MeetingNote
include Mongoid::Document
embedded_in :appointment
end
Isso significa que você pode recuperar as notas junto com um compromisso todos juntos, enquanto você precisaria de várias consultas se isso fosse uma associação. Você apenas tem que ter em mente o limite de tamanho de 16 MB para um único documento que pode entrar em jogo se você tiver um grande número de anotações de reunião.
Apenas para expandir isso, aqui estão os modelos estendidos com métodos que agem de maneira muito semelhante ao has_many: por meio de ActiveRecord retornando um proxy de consulta em vez de uma matriz de registros:
fonte
.pluck()
sin em vez de.map
é MUITO mais rápido. Você pode atualizar sua resposta para futuros leitores?undefined method 'pluck' for #<Array:...>
A solução Steven Soroka é realmente ótima! Não tenho a reputação de comentar uma resposta (é por isso que estou adicionando uma nova resposta: P), mas acho que usar o mapa para um relacionamento é caro (especialmente se o seu relacionamento has_many tiver centenas | milhares de registros) porque ele fica os dados do banco de dados, constroem cada registro, gera o array original e então itera sobre o array original para construir um novo com os valores do bloco dado.
Usar depenar é mais rápido e talvez a opção mais rápida.
Aqui estão algumas estatísticas com Benchmark.measure:
Estou usando apenas 250 compromissos. Não se esqueça de adicionar índices a: patient_id e: doctor_id no documento de compromisso!
Espero que ajude, obrigado pela leitura!
fonte
undefined method 'pluck' for #<Array:...>
Eu quero responder a essa questão da perspectiva da associação autorreferencial, não apenas da perspectiva has_many: por meio da perspectiva.
Digamos que temos um CRM com contatos. Os contatos terão relacionamentos com outros contatos, mas em vez de criar um relacionamento entre dois modelos diferentes, estaremos criando um relacionamento entre duas instâncias do mesmo modelo. Um contato pode ter muitos amigos e ser amigo de muitos outros contatos, então teremos que criar um relacionamento muitos para muitos.
Se estivermos usando um RDBMS e ActiveRecord, usaríamos has_many: through. Portanto, precisaríamos criar um modelo de associação, como Amizade. Este modelo teria dois campos, um contact_id que representa o contato atual que está adicionando um amigo e um friend_id que representa o usuário do qual está fazendo amizade.
Mas estamos usando MongoDB e Mongoid. Conforme declarado acima, o Mongoid não tem has_many: through ou um recurso equivalente. Não seria tão útil com o MongoDB porque não oferece suporte a consultas de junção. Portanto, para modelar um relacionamento muitos-muitos em um banco de dados não-RDBMS como o MongoDB, você usa um campo que contém uma matriz de chaves 'estrangeiras' em cada lado.
Conforme afirma a documentação:
Agora, para uma associação de autorreferência no MongoDB, você tem algumas opções.
Qual é a diferença entre contatos relacionados e contatos que têm muitos e pertencem a muitas clínicas? Enorme diferença! Um é um relacionamento entre duas entidades. Outro é uma auto-referência.
fonte