98 votes

Comment implémenter has_many : par le biais de relations avec Mongoid et mongodb ?

En utilisant cet exemple mis à jour le de ses guides Rails 3, comment on modélise un relationnel « has_many : par » association aide mongoid ?

Le défi est que mongoid ne supporte pas has_many : grâce à l’instar de ActiveRecord.

153voto

Steve Points 9867

Mongoid n'a pas has_many :through ou une fonctionnalité équivalente. Il ne serait pas utile avec MongoDB, car il ne prend pas en charge les requêtes de jointure de sorte que même si vous pourriez faire référence à un de la collection via un autre, il aurait encore besoin de plusieurs requêtes.

https://github.com/mongoid/mongoid/issues/544

Normalement, si vous avez une beaucoup beaucoup de relation dans un SGBDR vous modèle différemment dans MongoDB à l'aide d'un champ contenant un tableau de 'l'étranger' touches 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 permettrait d'éliminer la table de jointure et il aurait un effet similaire à has_many :through en termes d'accès à "l'autre côté". Mais dans votre cas, c'est probablement pas approprié parce que votre table de jointure est un Rendez-vous de la classe qui porte des informations supplémentaires, non seulement l'association.

Comment le modèle de cette dépend dans une certaine mesure sur les requêtes que vous avez besoin de courir, mais il semble que vous aurez besoin d'ajouter de la Nomination de modèle et de définir des associations de Patients et des Médecins à quelque chose 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 des relations dans MongoDB, vous avez toujours un choix à faire entre incorporé ou des documents associés. Dans votre modèle, je suppose que MeetingNotes êtes un bon candidat pour un intégré à la relation.

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 si c'était une association. Vous avez juste à garder à l'esprit le 16 MO de limite de taille pour un seul document qui pourrait entrer en jeu si vous avez un très grand nombre de notes de réunion.

42voto

Steven Soroka Points 8446

Juste pour élargir sur ce, voici les modèles étendus avec les méthodes de loi très similaire à la has_many :through de ActiveRecord par le retour d'une requête proxy au lieu d'un tableau d'enregistrements:

class Physician
  include Mongoid::Document
  has_many :appointments

  def patients
    Patient.in(id: appointments.map(&:patient_id))
  end
end

class Appointment
  include Mongoid::Document
  belongs_to :physician
  belongs_to :patient
end

class Patient
  include Mongoid::Document
  has_many :appointments

  def physicians
    Physician.in(id: appointments.map(&:physician_id))
  end
end

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X