【发布时间】:2010-05-06 11:50:09
【问题描述】:
请解释两者的区别 has_and_belongs_to_many 和 has_many 通过关系。何时何地使用哪一个?
【问题讨论】:
标签: ruby-on-rails
请解释两者的区别 has_and_belongs_to_many 和 has_many 通过关系。何时何地使用哪一个?
【问题讨论】:
标签: ruby-on-rails
据我所知,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
等等。
【讨论】:
最简单的经验法则是,如果您需要将关系模型作为独立实体使用,您应该设置一个 has_many :through 关系。如果您不需要对关系模型做任何事情,那么设置 has_and_belongs_to_many 关系可能会更简单(尽管您需要记住在数据库中创建连接表)。 如果您需要验证、回调或连接模型上的额外属性,则应使用 has_many :through。
【讨论】:
我的经验法则是,我可以在这里使用复选框列表吗?如果是这样,那么它是一个 habtm 协会。如果我需要复选框来捕获更多关于关系的信息,而不仅仅是它所属的是/否,那么使用 has_many :through。 HABTM 就像使用带有 simple_form collection_check_boxes 的 _ids 方法一样简单。 Has_many :through 经常涉及accepts_nested_attributes_for。
【讨论】:
如果您需要验证、回调或连接模型上的额外属性,您应该使用 has_many :through。
【讨论】:
根据我的经验,使用has_many: through 总是更好,因为您可以将时间戳添加到表中。很多时候,在调试通过 HABTM 连接的一些 ActiveRecord 对象时,我错过了 created_at、updated_at 时间戳来了解实际发生的情况。
所以请记住,它可以帮助您在当时的上下文中调试、调查与数据关系有关的问题,因为没有它,您在创建或更新关系时是“盲目的”。
【讨论】:
如果您不需要连接表上的任何额外数据或验证,许多答案都表明您应该使用has_and_belongs_to_many 与has_many through:。
但是,请注意不要采用这种方法。在应用程序开发的早期阶段,几乎不可能知道您在项目生命周期的遥远未来可能需要哪些额外的功能或验证。如果您决定使用has_and_belongs_to_many,并希望在 2 年后添加一个简单的数据点或验证,那么迁移此更改将非常困难且容易出错。为了安全起见,默认为has_many :through
【讨论】:
最简单的经验法则是,如果您需要将关系模型作为独立实体使用,则可以使用 has_many :through 关系。
如果您不需要对关系模型做任何事情,设置has_and_belongs_to_many relationship 可能会更简单(尽管您需要记住在数据库中创建连接表)。
如果您需要验证、回调或连接模型的额外属性,您应该使用has_many :through。
【讨论】:
Rails 提供了两种不同的方式来声明模型之间的多对多关系。第一种方式是使用has_and_belongs_to_many,可以直接进行关联:
声明多对多关系的第二种方法是使用 has_many :through。 这会通过 join 模型间接建立关联:
如果您需要验证、回调或连接模型上的额外属性,您应该使用 has_many :through。
【讨论】: