【发布时间】:2014-03-12 13:16:39
【问题描述】:
我正在开发一个具有“产品”模型的 Rails 应用程序。我希望能够将产品相互关联。示例:产品 1 与产品 2、产品 3 相关,反之亦然。我将如何在 Rails 中实现这一点?我在考虑一个连接表,但由于我使用的是同一个表作为关系点,我不确定它是如何工作的。
【问题讨论】:
标签: ruby-on-rails ruby
我正在开发一个具有“产品”模型的 Rails 应用程序。我希望能够将产品相互关联。示例:产品 1 与产品 2、产品 3 相关,反之亦然。我将如何在 Rails 中实现这一点?我在考虑一个连接表,但由于我使用的是同一个表作为关系点,我不确定它是如何工作的。
【问题讨论】:
标签: ruby-on-rails ruby
未经测试,凭记忆,我想你会想要这样的东西:
class ProductLink < ActiveRecord::Base
belongs_to :parent_product, :class_name => 'Product'
belongs_to :child_product, :class_name => 'Product'
end
class Product < ActiveRecord::Base
has_many :parent_links, :class_name => 'ProductLink', :foreign_key => :parent_product_id
has_many :child_links, :class_name => 'ProductLink', :foreign_key => :child_product_id
end
ProductLink(或您选择的任何名称)将能够包含一个或多个描述关系的附加字段。
您可以使用has_and_belongs_to_many 使其工作,尽管我想这需要一个“products_products”表,这可能有点压力。
【讨论】:
使用acts_as_follower gem。 http://github.com/tcocca/acts_as_follower/tree/master。它在跟随关系方面非常灵活,并提供了通用的跟随语义。
真的很简单,而且效果很好。只需用它来表示产品 1 跟随产品 2/3 等等。
【讨论】:
你是对的,你需要一个连接表。它需要两个字段,这两个字段都是返回产品表的外键。
所以像 ProductRelation 表一样,其中包含 FirstProduct 和 SecondProduct 字段(这些字段可能有更好的名称)然后您知道 FirstProduct 与 SecondProduct 相关...然后您对相关产品的查询将非常简单。
【讨论】:
试试 Acts_as_nested 插件!
https://github.com/bbommarito/acts_as_nested_set
也许 Ryan Bates 的截屏视频也可以帮助您:
http://railscasts.com/episodes/163-self-referential-association
【讨论】:
我发现这个答案最有用: Ruby On Rails - many to many between the same table
由此,我成功实现了模型与其自身的双向多对多关联。在您的情况下,它将如下所示:
class Product < ActiveRecord::Base
...
has_many :parent_product_map, class_name: 'ProductMap', foreign_key: 'child_product_id'
has_many :parent_products, through: :parent_product_map, source: :parent_product, class_name: 'Product'
has_many :child_product_map, class_name: 'ProductMap', foreign_key: 'parent_product_id'
has_many :child_products, through: :child_product_map, source: :child_product, class_name: 'Product'
...
end
class ProductMap < ActiveRecord::Base
attr_accessible :child_product_id, :id, :parent_product_id
belongs_to :child_product, foreign_key: 'child_product_id', class_name: 'Product'
belongs_to :parent_product, foreign_key: 'parent_product_id', class_name: 'Product'
end
class CreateProductMap < ActiveRecord::Migration
def change
create_table :product_maps do |t|
t.integer :id
t.timestamps
t.integer :child_product_id
t.integer :parent_product_id
end
end
【讨论】: