2009-03-18 3 views
22

Есть ли что-то явно неправильное в использовании ассоциаций has_and_belongs_to_many в rails вместо has_many: через? Я знаю thesearticlesdescribing различия и работа вокруг, но они с 2006 года. Из того, что я прочитал на SO, кажется, что люди считают, что habtm старый и неуклюжий, но что, если простые многие к многим присоединяются к Вам не нужна модель?has_and_belongs_to_many in Rails

Мысли?

ответ

29

has_and_belongs_to_many предназначено для простых отношений "многие ко многим".

has_many: с другой стороны, предназначен для косвенных отношений «один ко многим» или «многих ко многим» со свойствами.

Если вы ищете только простые отношения «многие ко многим», я не вижу причин не использовать has_and_belongs_to_many.

Пример многие ко многим отношений:

Пользователь принадлежит к нулю или более групп, а группа имеет ноль или более членов (пользователей).

Пример многие ко многим отношений со свойствами:

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

Например, Алиса может быть администратором группы A и модератором в группе B. Вы можете сохранить это свойство в таблице соединений.

Пример непрямой один-ко-многим:

категория имеет ноль или более подкатегории, и каждый суб-категория имеет ноль или больше элементов.

Категория, следовательно, имеет ноль или более предметов через свои подкатегории.

Рассмотрим эти категории:

Продукты питания → Фрукты, Овощи
Фрукты → Яблоко, апельсин и т.д.
Овощи → Морковь, сельдерей и т.д.

поэтому:

Продукты питания → Apple, Orange, морковь, сельдерей и т. Д.

+2

Чтобы понять рекурсию, вы должны сначала понять рекурсию. Я думаю, что ваш ответ может быть более ясным или демонстративным в отношении отношений «многие ко многим» со свойствами по отношению к отношениям «многие-ко-многим» без свойств. –

+3

Позвольте мне привести несколько примеров. –

+0

+1, что на самом деле мне тоже помогло. –

3

Нет ничего плохого в использовании has_and_belongs_to_many, если вам не нужна модель соединения. Я только что использовал его в недавнем проекте.

+0

как вы можете использовать это с 'accept_nested_attribute_for'? спасибо – hqt

3

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

+7

Никогда? В самом деле? Как никогда, как в «Я никогда не использую goto»? –

+0

Я полагаю, что если бы я мог найти отношения, где было бы логически невозможно добавить данные, я мог бы пойти с HABTM. В противном случае я бы пошел с has_many: through. – srboisvert

3

Я думаю об этом таким образом. Предполагая, что вы уже нашли, что вам нужно много-ко-многим модель:

X----1 
    __/ 
/
Y----2 
    __/ 
/ 
Z----3 

(x-> 1 y-> 1,2 z-> 2,3)

Используйте отношения HABTM если вам НЕ нужно хранить информацию о каждой из строк на моей (надеюсь, узнаваемой) картинке выше.

Если вам нужно сохранить информацию об этих линиях (отношениях), используйте «сквозной».

Так что если вы просто говорите, что люди [XYZ] имеют и принадлежат к проектам [123], но не нужно ничего говорить о человеке X в проекте 1, используйте HABTM.

Если вы хотите сказать, что человек X имеет проект 1 и ему был присвоен этот проект на заданную дату, у вас внезапно возникнет необходимость в этом отношении и лучше использовать HMT.

+3

+1 для сладкой диаграммы – jbnunn

+1

Hoho, спасибо! ASCII графика для победы! – Jon