Mongoid не имеет has_many: through или аналогичной функции. Это было бы не так полезно с MongoDB, потому что он не поддерживает запросы соединения, поэтому даже если вы можете ссылаться на связанную коллекцию через другую, все равно потребуется несколько запросов.
https://github.com/mongoid/mongoid/issues/544
Обычно, если у вас есть отношение «многие-многие» в РСУБД, вы можете моделировать это по-другому в MongoDB, используя поле, содержащее массив «внешних» ключей с обеих сторон. Например:
class Physician
include Mongoid::Document
has_and_belongs_to_many :patients
end
class Patient
include Mongoid::Document
has_and_belongs_to_many :physicians
end
Другими словами, вы удалите таблицу соединений, и это будет иметь эффект, аналогичный has_many: through с точки зрения доступа к «другой стороне». Но в вашем случае это, вероятно, не подходит, потому что ваша таблица соединений - это класс Appointment, который несет некоторую дополнительную информацию, а не только ассоциацию.
То, как вы это моделируете, в некоторой степени зависит от запросов, которые вам нужно запустить, но кажется, что вам нужно будет добавить модель встречи и определить ассоциации с пациентом и врачом примерно так:
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
С отношениями в MongoDB вам всегда нужно делать выбор между встроенными или связанными документами. В вашей модели я бы предположил, что MeetingNotes - хороший кандидат для встроенных отношений.
class Appointment
include Mongoid::Document
embeds_many :meeting_notes
end
class MeetingNote
include Mongoid::Document
embedded_in :appointment
end
Это означает, что вы можете получать заметки вместе с встречей все вместе, тогда как вам потребовалось бы несколько запросов, если бы это была связь. Вам просто нужно иметь в виду ограничение размера 16 МБ для одного документа, которое может вступить в силу, если у вас очень большое количество заметок к собранию.
Чтобы расширить это, вот модели, расширенные методами, которые действуют очень похоже на has_many: through из ActiveRecord, возвращая прокси запроса вместо массива записей:
источник
.pluck()
sinstead of намного.map
быстрее. Можете ли вы обновить свой ответ для будущих читателей?undefined method 'pluck' for #<Array:...>
Решение Стивена Сорока действительно великолепное! У меня нет репутации, чтобы прокомментировать ответ (вот почему я добавляю новый ответ: P), но я думаю, что использование карты для отношений обходится дорого (особенно, если у ваших отношений has_many есть hunders | тысячи записей), потому что он получает данные из базы данных, построить каждую запись, создать исходный массив, а затем выполнить итерацию по исходному массиву, чтобы построить новый со значениями из данного блока.
Использование pluck - более быстрый и, возможно, самый быстрый вариант.
Вот некоторая статистика с Benchmark.measure:
Я использую всего 250 встреч. Не забудьте добавить индексы к: Patient_id и: Physician_id в документе о встрече!
Надеюсь, это поможет, спасибо за чтение!
источник
undefined method 'pluck' for #<Array:...>
Я хочу ответить на этот вопрос с точки зрения ассоциации, ссылающейся на себя, а не только с точки зрения has_many: через перспективу.
Допустим, у нас есть CRM с контактами. Контакты будут иметь отношения с другими контактами, но вместо создания отношений между двумя разными моделями мы будем создавать отношения между двумя экземплярами одной и той же модели. У контакта может быть много друзей, и многие другие контакты могут с ним дружить, поэтому нам придется создать отношения «многие ко многим».
Если мы используем СУБД и ActiveRecord, мы бы использовали has_many: through. Таким образом, нам потребуется создать модель объединения, например Дружбу. Эта модель будет иметь два поля: contact_id, представляющий текущего контакта, который добавляет друга, и friend_id, представляющий пользователя, с которым дружат.
Но мы используем MongoDB и Mongoid. Как указано выше, в Mongoid нет has_many: through или аналогичной функции. Это было бы не так полезно с MongoDB, потому что он не поддерживает запросы на соединение. Следовательно, чтобы смоделировать отношения «многие-многие» в базе данных, отличной от СУБД, такой как MongoDB, вы используете поле, содержащее массив «внешних» ключей с обеих сторон.
Как указано в документации:
Теперь для ассоциации с саморегулированием в MongoDB у вас есть несколько вариантов.
В чем разница между родственными контактами и контактами, имеющими много и принадлежащими многим практикам? Огромная разница! Один - это отношения между двумя сущностями. Другое - это ссылка на себя.
источник