【问题标题】:has_and_belongs_to_many vs has_many throughhas_and_belongs_to_many vs has_many 通过
【发布时间】:2010-05-06 11:50:09
【问题描述】:

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

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

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

    等等。

    【讨论】:

    • 请注意,该表需要按字母顺序命名,即 categories_stories 表而不是 stories_categories - 这是使其工作的约定。
    • 谢谢,我现在改了帖子
    • 为什么它们必须是字母@Will?
    • @ctilley79 这是使用的约定。因此,当建立关联时,它知道要查找哪个表
    • @Will 我会得到完全相同的东西。它不会在写入数据库时​​包含附加属性。我的问题是活动记录正在写入数据库的创建语句。这可能会有所帮助
    【解决方案2】:

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

    【讨论】:

    • 我还要补充一点,rails 有很多方法插入到 has_and_belongs_to_many 而不是 has_many :through。所有的方法,比如为关联分配一组值,似乎都没有显示在 has_many 的文档中:通过guides.rubyonrails.org/…
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      如果您需要验证、回调或连接模型上的额外属性,您应该使用 has_many :through。

      【讨论】:

        【解决方案5】:

        根据我的经验,使用has_many: through 总是更好,因为您可以将时间戳添加到表中。很多时候,在调试通过 HABTM 连接的一些 ActiveRecord 对象时,我错过了 created_atupdated_at 时间戳来了解实际发生的情况。

        所以请记住,它可以帮助您在当时的上下文中调试、调查与数据关系有关的问题,因为没有它,您在创建或更新关系时是“盲目的”。

        【讨论】:

          【解决方案6】:

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

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

          【讨论】:

          • 你能解释一下为什么这会很危险并且容易出错吗? HABTM 与 has_many :through 相同,只是没有模型。您可以非常优雅地将 HABTM 转换为虽然。
          • 这是您问题的一个很好的答案,@grepsedawk:flatironschool.com/blog/…
          【解决方案7】:

          最简单的经验法则是,如果您需要将关系模型作为独立实体使用,则可以使用 has_many :through 关系。

          如果您不需要对关系模型做任何事情,设置has_and_belongs_to_many relationship 可能会更简单(尽管您需要记住在数据库中创建连接表)。

          如果您需要验证、回调或连接模型的额外属性,您应该使用has_many :through

          【讨论】:

            【解决方案8】:

            Rails 提供了两种不同的方式来声明模型之间的多对多关系。第一种方式是使用has_and_belongs_to_many,可以直接进行关联:

            声明多对多关系的第二种方法是使用 has_many :through。 这会通过 join 模型间接建立关联:

            如果您需要验证、回调或连接模型上的额外属性,您应该使用 has_many :through

            【讨论】:

            • 这不会为一个非常古老(> 10 年!)的线程添加任何内容。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-03-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多