Rails中的has_and_belongs_to_many

22

在Rails中,使用has_and_belongs_to_many关联而不是has_many:through关联有明显的问题吗?我知道有这些 文章 描述差异和解决方法,但它们来自2006年。从我在SO上阅读的内容来看,人们似乎认为habtm已经过时而且笨重,但是如果你正在寻找一个简单的多对多连接而不需要模型呢?

你有什么想法?

4个回答

29

has_and_belongs_to_many 用于简单的多对多关系。

而 has_many :through 则用于间接的一对多关系,或带有属性的多对多关系。

如果您只需要一个简单的多对多关系,我看不出使用 has_and_belongs_to_many 的任何理由。

例子:多对多关系

用户属于零个或多个群组,而群组具有零个或多个成员(用户)。

例子:具有属性的多对多关系

用户属于零个或多个群组,而群组具有零个或多个拥有职级的成员。

例如,Alice 可能是 Group A 中的管理员和 Group B 中的版主。您可以在联接表中保存此属性。

例子:间接的一对多关系

一个类别有零个或多个子类别,每个子类别都有零个或多个项。

因此,每个类别都通过其子类别具有零个或多个项。

考虑以下类别:

食品 → 水果、蔬菜
水果 → 苹果、橘子等
蔬菜 → 胡萝卜、芹菜等

因此:

食品 → 苹果、橘子、胡萝卜、芹菜等。


2
要理解递归,你必须先理解递归。我认为你的答案在涉及带属性的多对多关系和不带属性的多对多关系时可以更清晰或更具有示范性。 - Oliver N.
你如何在 accept_nested_attribute_for 中使用它?谢谢。 - hqt

3

我这样考虑。假设你已经发现需要一个多对多的模型:

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

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

如果您不需要存储有关上图中每行的信息,则使用HABTM关系。

如果您需要存储这些行(关系)的信息,请使用“through”。

因此,如果您只是说人们[XYZ]拥有并属于项目[123],但不需要在项目1上说任何关于X的事情,请使用HABTM。

如果您想说人X在给定日期被分配了项目1,并且要为该特定关系创建适当的数据,则最好使用HMT。


3
如果您不需要关联模型,使用has_and_belongs_to_many是没有问题的。我最近在一个项目中就使用了它。

1
你如何在 accept_nested_attribute_for 中使用它?谢谢。 - hqt

3

我不会使用HABTM,不是因为对优雅的担忧,而是因为即使现在看不到点,我总能想象未来想要向关系中添加数据。因为懒惰,我希望只需将列添加到连接中,而无需重新设计关系并添加列。


7
真的从不?像“我从不使用goto”那样的从不? - Jason Punyon
我认为,如果我能想出一种关系,在这种关系中逻辑上不可能添加数据,那么我可能会选择使用HABTM。否则,我将选择使用has_many: through。 - srboisvert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接