rails 4的关系has_many和belongs_to

时间:2014-08-29 17:59:30

标签: ruby-on-rails

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

项目

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

ItemAddon

  id:integer
  name:string
  price:decimal

ItemAvailableAddon

  id:integer
  item_id:integer
  item_addon_id:integer
  • 商品是通用商品
  • 附加组件是一个额外的,可以显示一个或多个项目,但它不直接绑定到一个项目;相反,它通过ItemAvailableAddon
  • 绑定
  • 可用项目Addon将项目绑定在一起并添加项目。

这些是正确的关系吗?

  • ItemAvailableAddon belongs_to item
  • ItemAvailableAddon belongs_to item_addon
  • 项目has_many item_available_addon
  • ItemAddon has_many item_available_addon

部分帽子令我困惑的是多人关系

1 个答案:

答案 0 :(得分: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这样简单明了的东西):这将告诉你哪些表不存在:创建它。这就是我确定迁移名称的方式。
  • 如果上述试用和错误看起来很尴尬,您可以手动指定联接表的名称。你不必坚持Rails的猜测。
  • 该链接表示使用t.integer :<model>_id,但它与t.references :<model>相同,这是一种约定。我更喜欢使用后者,因为它更具语义性(它是一个整数,但它作为参考:不是每个整数都是参考)。
  • 表格创建中的
  • id: false。这很重要。
  • 我看到有人在每个字段后添加null: false。我怀疑如果正确使用关联,这应该会产生任何影响。因为否则会发生任何事情。
  • 没有ItemAddonItem模型或类似的东西。这就是has_and_belongs_to_many的全部内容。普通连接表,没有其他目的,但保持关联。

这就是全部。迁移,你应该全部设置。只有一件事:如果ItemAddon只是Addon,事情会变得更简单。无论如何它都是相关的。