【问题标题】:rails 4 relationships has_many and belongs_torails 4 关系 has_many 和 belongs_to
【发布时间】:2014-10-23 18:55:38
【问题描述】:

我有 3 个模型的以下数据库架构。

物品

  id:integer
  name:string
  order:integer (sort order)
  description:text
  price:decimal

物品插件

  id:integer
  name:string
  price:decimal

ItemAvailableAddon

  id:integer
  item_id:integer
  item_addon_id:integer
  • 商品是普通待售商品
  • 附加组件是可以出现在一个或多个项目上的附加组件,但它不直接与一个项目相关联;相反,它通过 ItemAvailableAddon 绑定
  • 可用的物品插件将物品和插件联系在一起。

这些是正确的关系吗?

  • ItemAvailableAddon 属于_to 项
  • ItemAvailableAddon 属于_to item_addon
  • 项目 has_many item_available_addon
  • ItemAddon has_many item_available_addon

让我困惑的是many_many关系

【问题讨论】:

标签: ruby-on-rails


【解决方案1】:

真的很像"has many through"。

Item:

has_many :item_available_addons
has_many :item_addons, through: :item_available_addons

ItemAddon:

has_many :item_available_addons
has_many :items, through: :item_available_addons

ItemAvailableAddon:

belongs_to :item
belongs_to :item_addon

我对看起来相似的型号名称有点困惑,但结构应该是这个或类似的。

如果“可用性事实”只是一个链接并且不需要额外数据(例如,插件与项目的关系类型:例如,如果需要这种插件,请考虑使用 has_and_belongs_to_many或可选)。否则,你很乐意这样做。

has_and_belongs_to_many

工作更简单,并且不是那么可定制。 但是设置它会更容易,因为它不需要维护额外的模型。不过,仍然需要一张额外的桌子。您根本不需要ItemAvailableAddon 模型。所以:

Item

has_and_belongs_to_many :item_addons

ItemAddon

has_and_belongs_to_many :items

现在是棘手的部分。连接表。还不赶紧迁移,先阅读完整答案:

rails g migration CreateItemAddonsItems item:references item_addon:references

这将为您提供一个简单的迁移您需要编辑as specified here:

class CreateItemAddonsItems < ActiveRecord::Migration
  def change
    create_table :item_addons_items, id: false do |t|
      t.references :item
      t.references :item_addon
    end
  end
end

注意事项:

  • 我不太明白 Rails 如何确定默认连接表名称背后的逻辑(他们说这是词法顺序,但是...),但试验总是有效的:在指定关联后不要进行任何迁移:fire启动 Rails 控制台并尝试使用该关联(类似Item.first.item_addons 的简单明了的东西):它会告诉您哪个表不存在:创建它。这就是我确定迁移名称的方式。
  • 如果上面描述的 trial&error 看起来很尴尬,您可以手动指定连接表的名称。您不必拘泥于 Rails 的猜测。
  • 链接说使用t.integer :&lt;model&gt;_id,但它与t.references :&lt;model&gt; 相同,这是一个约定。我更喜欢使用后者,因为它更具语义(它是一个整数,但它可以作为参考:并非每个整数都是参考)。
  • id: false 在表创建中。这很重要。
  • 我见过有人在每个字段后添加null: false。如果正确使用关联,我怀疑这应该有任何影响。因为否则任何事情都可能发生。
  • 没有ItemAddonItem 模型或类似的东西。这就是has_and_belongs_to_many 的全部意义所在。一个简单的连接表,除了维护关联之外没有其他用途。

就是这样。迁移,你应该一切准备就绪。只有一件事:如果ItemAddon 只是Addon,事情看起来会简单得多。反正是有关联的。

【讨论】:

  • 这似乎效果很好。你能编辑你的答案并用 has_and_belongs_to_many 举一个例子吗?
  • @ChrisMuench 从代码中删除所有要加入模型的引用(through 键和额外的has_manys),并将has_many 替换为has_and_belongs_to_many - 你就拥有了。但请注意:它需要一些不同的数据库结构。当我对其进行正确测试时,我将添加一个示例,我以前从未使用过 HABTM(从来没有使用过)。 HABTM 与 HMT 基本相同,只是连接模型是隐式的和准系统的:甚至不应该有主键。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-27
  • 1970-01-01
相关资源
最近更新 更多