has_and_belongs_to_many vs has_many through

时间:2010-05-06 11:50:09

标签: ruby-on-rails

请解释一下之间的区别 has_and_belongs_to_many和has_many通过关系。何时何地使用哪一个?

6 个答案:

答案 0 :(得分:100)

据我所知,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 

等等。

答案 1 :(得分:34)

来自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。

答案 2 :(得分:13)

我的经验法则是,我可以在这里查看复选框列表吗?如果是这样,那么它就是一个habtm协会。如果我需要复选框来捕获关于关系的更多信息,而不仅仅是是/否,那么请使用has_many:through。 HABTM就像使用带有simple_form collection_check_boxes的_ids方法一样简单。 Has_many:通常涉及accepts_nested_attributes_for。

答案 3 :(得分:4)

如果您需要在连接模型上进行验证,回调或额外属性,则应使用has_many:through。

答案 4 :(得分:1)

许多答案都表明,如果不需要联接表上的任何额外数据或验证,则应该使用has_and_belongs_to_manyhas_many through:

但是,请注意采用这种方法。在应用程序开发的早期阶段,几乎不可能不可能知道项目生命周期的未来可能需要哪些额外的功能或验证。如果您决定使用has_and_belongs_to_many,并希望在未来2年内添加一个简单的数据点或验证,那么迁移此更改将非常困难且容易出错。为了安全起见,默认设置为has_many :through

答案 5 :(得分:1)

根据我的经验,最好使用has_many: through,因为至少可以在表中添加时间戳。很多时候,在调试通过HABTM连接的某些ActiveRecord对象时,我缺少了created_atupdated_at时间戳。因此请记住,它可以帮助您在时间范围内调试,调查与数据关系有关的问题,因为没有它,您在创建或更新关系时会“盲目”。