has_and_belongs_to_many в Rails - PullRequest
       12

has_and_belongs_to_many в Rails

22 голосов
/ 18 марта 2009

Есть ли что-то явно не так с использованием ассоциаций has_and_belongs_to_many в рельсах вместо has_many: through? Мне известны эти статьи , описывающие различия и обходные пути, но они относятся к 2006 году. Из того, что я читал на SO, кажется, что Вы думаете, что habtm старый и неуклюжий, но что, если вы просто присоединяетесь к многим и многим без нужной модели - это то, что вы ищете?

Мысли

Ответы [ 4 ]

29 голосов
/ 18 марта 2009

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

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

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

Пример отношения «многие ко многим»:

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

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

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

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

Пример косвенного отношения один ко многим:

Категория имеет ноль или более подкатегорий, а каждая подкатегория имеет ноль или более элементов.

Поэтому категория имеет ноль или более элементов в своих подкатегориях.

Рассмотрим следующие категории:

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

поэтому:

Еда → Яблоко, Апельсин, Морковь, Сельдерей и т. Д.

3 голосов
/ 25 мая 2011

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

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

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

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

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

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

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

3 голосов
/ 18 марта 2009

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

3 голосов
/ 18 марта 2009

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

...