Mongoid n'a pas has_many: through ou une fonctionnalité équivalente. Cela ne serait pas si utile avec MongoDB car il ne prend pas en charge les requêtes de jointure, donc même si vous pouviez référencer une collection associée via une autre, cela nécessiterait toujours plusieurs requêtes.
https://github.com/mongoid/mongoid/issues/544
Normalement, si vous avez une relation plusieurs-plusieurs dans un SGBDR, vous modéliseriez cela différemment dans MongoDB en utilisant un champ contenant un tableau de clés «étrangères» de chaque côté. Par exemple:
class Physician
include Mongoid::Document
has_and_belongs_to_many :patients
end
class Patient
include Mongoid::Document
has_and_belongs_to_many :physicians
end
En d'autres termes, vous élimineriez la table de jointure et cela aurait un effet similaire à has_many: through en termes d'accès à «l'autre côté». Mais dans votre cas, ce n'est probablement pas approprié car votre table de jointure est une classe de rendez-vous qui contient des informations supplémentaires, pas seulement l'association.
La façon dont vous modélisez cela dépend dans une certaine mesure des requêtes que vous devez exécuter, mais il semble que vous deviez ajouter le modèle de rendez-vous et définir des associations entre le patient et le médecin, comme ceci:
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
Avec les relations dans MongoDB, vous devez toujours faire un choix entre des documents intégrés ou associés. Dans votre modèle, je suppose que MeetingNotes est un bon candidat pour une relation intégrée.
class Appointment
include Mongoid::Document
embeds_many :meeting_notes
end
class MeetingNote
include Mongoid::Document
embedded_in :appointment
end
Cela signifie que vous pouvez récupérer les notes avec un rendez-vous tous ensemble, alors que vous auriez besoin de plusieurs requêtes s'il s'agissait d'une association. Il suffit de garder à l'esprit la taille limite de 16 Mo pour un seul document qui pourrait entrer en jeu si vous avez un très grand nombre de notes de réunion.
Juste pour développer cela, voici les modèles étendus avec des méthodes qui agissent très similaires à has_many: through d'ActiveRecord en renvoyant un proxy de requête au lieu d'un tableau d'enregistrements:
la source
.pluck()
péché au lieu de.map
est BIEN PLUS rapide. Pouvez-vous mettre à jour votre réponse pour les futurs lecteurs?undefined method 'pluck' for #<Array:...>
La solution Steven Soroka est vraiment géniale! Je n'ai pas la réputation de commenter une réponse (c'est pourquoi j'ajoute une nouvelle réponse: P) mais je pense que l'utilisation de map pour une relation coûte cher (surtout si votre relation has_many a des centaines | des milliers d'enregistrements) les données de la base de données, construisez chaque enregistrement, génère le tableau d'origine, puis itère sur le tableau d'origine pour en créer un nouveau avec les valeurs du bloc donné.
L'utilisation de la pince est plus rapide et peut-être l'option la plus rapide.
Voici quelques statistiques avec Benchmark.measure:
J'utilise seulement 250 rendez-vous. N'oubliez pas d'ajouter des index à: patient_id et: doctor_id dans le document de rendez-vous!
J'espère que cela aide, merci d'avoir lu!
la source
undefined method 'pluck' for #<Array:...>
Je veux répondre à cette question du point de vue de l'association auto-référencée, pas seulement du has_many: through perspective.
Disons que nous avons un CRM avec des contacts. Les contacts auront des relations avec d'autres contacts, mais au lieu de créer une relation entre deux modèles différents, nous créerons une relation entre deux instances du même modèle. Un contact peut avoir de nombreux amis et se lier d'amitié avec de nombreux autres contacts, nous allons donc devoir créer une relation plusieurs-à-plusieurs.
Si nous utilisons un SGBDR et ActiveRecord, nous utiliserions has_many: through. Ainsi, nous aurions besoin de créer un modèle de jointure, comme l'amitié. Ce modèle aurait deux champs, un contact_id qui représente le contact actuel qui ajoute un ami et un friend_id qui représente l'utilisateur qui se lie d'amitié.
Mais nous utilisons MongoDB et Mongoid. Comme indiqué ci-dessus, Mongoid n'a pas has_many: through ou une fonctionnalité équivalente. Cela ne serait pas si utile avec MongoDB car il ne prend pas en charge les requêtes de jointure. Par conséquent, afin de modéliser une relation plusieurs-plusieurs dans une base de données non SGBDR comme MongoDB, vous utilisez un champ contenant un tableau de clés «étrangères» de chaque côté.
Comme l'indique la documentation:
Maintenant, pour une association d'auto-référencement dans MongoDB, vous avez quelques options.
Quelle est la différence entre des contacts liés et des contacts ayant plusieurs et appartenant à de nombreuses pratiques? Énorme différence! L'une est une relation entre deux entités. L'autre est une auto-référence.
la source