简体   繁体   English

轨道4关系has_many和belongs_to

[英]rails 4 relationships has_many and belongs_to

I have the following database schema for 3 models. 我有以下3种模型的数据库架构。

Item 项目

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

ItemAddon ItemAddon

  id:integer
  name:string
  price:decimal

ItemAvailableAddon ItemAvailableAddon

  id:integer
  item_id:integer
  item_addon_id:integer
  • An item is generic item for sale 一个项目是待售的通用项目
  • An add-on is an extra that can appear for 1 or more items, but it isn't directly tied to an item; 附件是一项可以显示1个或多个项目的附加项目,但并不与项目直接相关; instead it is tied though ItemAvailableAddon 而是通过ItemAvailableAddon绑定
  • Item Available Addon ties together items and add ons. 项目可用的附加项将项目和附加项绑定在一起。

Are these the correct relationships? 这些是正确的关系吗?

  • ItemAvailableAddon belongs_to item ItemAvailableAddon属于项目
  • ItemAvailableAddon belongs_to item_addon ItemAvailableAddon属于item_addon
  • Item has_many item_available_addon 项目has_many item_available_addon
  • ItemAddon has_many item_available_addon ItemAddon has_many item_available_addon

The part hat is confusing me is the many_many relationships 令我困惑的部分是多对多关系

It really looks like "has many through" . 看起来确实像“经历了很多”

An Item : 一个Item

has_many :item_available_addons
has_many :item_addons, through: :item_available_addons

An ItemAddon : 一个ItemAddon

has_many :item_available_addons
has_many :items, through: :item_available_addons

An ItemAvailableAddon : 一个ItemAvailableAddon

belongs_to :item
belongs_to :item_addon

I'm getting a bit confused by similarly-looking model names, but the structure should be this or similar. 我对外观相似的模型名称有些困惑,但是结构应该是这个或相似的。

Still, consider using has_and_belongs_to_many if an "availability fact" is just a link and requires no extra data (such as, type of relation of an addon to an item: like, say, if this sort of addon is required or optional). 尽管如此,如果“可用性事实”只是一个链接并且不需要额外的数据(例如,附加组件与项目的关系类型:例如,如果这种附加组件是必需的或可选的),请考虑使用has_and_belongs_to_many Otherwise, you're good to go with this. 否则,您最好这样做。

has_and_belongs_to_many has_and_belongs_to_many

Works simpler and is not so customizable. 工作更简单,也不是可定制的。 But setting it up can be easier since it doesn't require maintaining an extra model. 但是设置它会更容易,因为它不需要维护额外的模型。 An extra table is still required though. 不过,仍然需要一个额外的表。 You will not need an ItemAvailableAddon model for this at all. 您完全不需要ItemAvailableAddon模型。 So: 所以:

An Item 一个Item

has_and_belongs_to_many :item_addons

An ItemAddon ItemAddon

has_and_belongs_to_many :items

And now for the tricky part. 现在是棘手的部分。 The join table. 联接表。 Don't hurry to migrate just yet, read the whole answer first: 现在不要着急迁移,请先阅读整个答案:

rails g migration CreateItemAddonsItems item:references item_addon:references

That will get you a bare-bones migration you need to edit 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

Notes: 笔记:

  • I don't quite get the logic behind how Rails determines the default join table name (they say it's lexical order, but...), but experimenting always works: after specifying an association don't make any migrations: fire up a Rails console and try to use that association (something plain and simple like Item.first.item_addons ): that will tell you what table does not exist: create it. 我不太了解Rails如何确定默认的联接表名称(他们说这是词法顺序,但是...)背后的逻辑,但是实验总是可行的:指定关联后不要进行任何迁移:启动Rails控制台并尝试使用该关联(类似于Item.first.item_addons简单明了的Item.first.item_addons ):它将告诉您不存在哪个表:创建它。 That's how I determined the migration name. 这就是我确定迁移名称的方式。
  • You can specify the name of a join table manually, if the trial&error described above seems awkward. 如果上述试错法看起来很尴尬,则可以手动指定联接表的名称。 You don't have to stick to Rails' guessing. 您不必遵循Rails的猜测。
  • The link says to use t.integer :<model>_id , but it's the same as t.references :<model> , it's a convention. 链接说要使用t.integer :<model>_id ,但是与t.references :<model> ,这是一个约定。 I prefer using the latter, since it's more semantic (it is an integer, but it serves as a reference: not every integer is a reference). 我更喜欢使用后者,因为它具有更多的语义(它是一个整数,但可以用作参考:并非每个整数都是参考)。
  • id: false in table creation. id: false在创建表时为id: false It's important. 这一点很重要。
  • I've seen people adding null: false after each field. 我见过人们在每个字段后添加null: false I doubt this should have any effect if association is used correctly. 我怀疑如果正确使用关联将不会产生任何效果。 Because otherwise anything can happen. 因为否则任何事情都会发生。
  • There isn't ItemAddonItem model or anything similar. 没有ItemAddonItem模型或任何类似的模型。 It's what has_and_belongs_to_many is all about. 这就是has_and_belongs_to_many的全部意义。 A plain join table with no other purpose but maintaining an association. 一个普通的联接表,除了保持关联外没有其他用途。

That's all. 就这样。 Migrate and you should be all set. 迁移后,您应该已经准备就绪。 Just one thing: things would look a lot simpler if ItemAddon were just Addon . 只是一件事:如果ItemAddon只是Addon事情看起来会简单得多。 It's associated anyway. 无论如何,它都是关联的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM