has_and_belongs_to_many против has_many через - PullRequest
71 голосов
/ 06 мая 2010

Пожалуйста, объясните разницу между has_and_belongs_to_many и has_many через отношения. Когда и где использовать какой?

Ответы [ 6 ]

101 голосов
/ 06 мая 2010

Насколько я помню, has_and_belongs_to_many дает вам простую таблицу поиска, которая ссылается на две ваши модели.

Например,

Истории могут принадлежать ко многим категориям. Категории могут иметь много историй.

Categories_Stories Table
story_id | category_id

has_many :through дает вам третью модель, которую можно использовать для хранения различной другой информации, которая не принадлежит ни одной из исходных моделей.

Например

Человек может подписаться на множество журналов. Журналы могут иметь много подписчиков.

Таким образом, мы можем иметь модель подписки посередине, которая дает нам таблицу, аналогичную предыдущему примеру, но с дополнительными свойствами.

Subscriptions Table
person_id | magazine_id | subscription_type | subscription_length | subscription_date 

и т. Д.

35 голосов
/ 06 мая 2010

С http://guides.rubyonrails.org/association_basics.html#choosing-between-has-many-through-and-has-and-belongs-to-many

Самое простое практическое правило заключается в том, что вы должны установить отношение has_many: through, если вам нужно работать с моделью отношений как с независимой сущностью. Если вам не нужно ничего делать с моделью отношений, может быть проще настроить отношение has_and_belongs_to_many (хотя вам нужно помнить о создании таблицы присоединения в базе данных). Вы должны использовать has_many: through, если вам нужны проверки, обратные вызовы или дополнительные атрибуты в модели соединения.

14 голосов
/ 08 июня 2013

Мое эмпирическое правило: могу ли я обойтись здесь со списком флажков? Если так, то это ассоциация habtm. Если мне нужен флажок, чтобы получить больше информации об отношениях, чем просто да / нет, то они принадлежат, тогда используйте has_many: through. HABTM так же прост, как и использование метода _ids с simple_form collection_check_boxes. Has_many: через часто включает acceptpts_nested_attributes_for.

4 голосов
/ 29 декабря 2015

Вы должны использовать has_many: through, если вам нужны проверки, обратные вызовы или дополнительные атрибуты в модели соединения.

2 голосов
/ 18 июля 2018

Во многих ответах уточняется, что вам следует использовать has_and_belongs_to_many против has_many through:, если вам не понадобятся какие-либо дополнительные данные или проверки в таблице соединений.

Однако , остерегайтесь такого подхода. На ранних стадиях разработки приложений почти невозможно узнать, какие дополнительные функции или проверки вам могут понадобиться в далеком будущем жизненного цикла вашего проекта. Если вы решили использовать has_and_belongs_to_many и хотите добавить одно простое назначение данных или проверку через 2 года, перенос этого изменения будет чрезвычайно трудным и подверженным ошибкам. Чтобы быть в безопасности, по умолчанию has_many :through

1 голос
/ 21 июня 2019

Исходя из моего опыта, всегда лучше использовать has_many: through, потому что, по крайней мере, вы можете добавлять метки времени в таблицу. Много раз при отладке некоторых ActiveRecord объектов, подключенных через HABTM, мне не хватало created_at, updated_at отметок времени. Так что имейте в виду, что это может помочь вам отладить, исследовать проблемы с отношениями данных в контексте времени, потому что без этого вы «слепы», когда отношения были созданы или обновлены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...