与同桌的多对多关系(Ruby on Rails)

时间:2009-06-12 15:06:24

标签: ruby-on-rails ruby

我正在开发一款具有“产品”型号的Rails应用。我希望能够将产品相互关联。示例:产品1与产品2,产品3相关,反之亦然。我将如何在Rails中实现这一目标?我在考虑一个连接表,但由于我使用相同的表作为关系点,我不确定它是如何工作的。

5 个答案:

答案 0 :(得分:3)

未经测试和记忆,我想你想要这样的东西:

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”表,这可能会有点紧张。

答案 1 :(得分:1)

使用acts_as_follower gem。 http://github.com/tcocca/acts_as_follower/tree/master。它在以下关系方面非常灵活,并提供通用的以下语义。

非常简单,效果很好。只是用它来说产品1跟随产品2/3等。

答案 2 :(得分:0)

你是对的,你需要一个联接表。它需要两个字段,这两个字段都是返回到products表的外键。

类似于带有FirstProduct和SecondProduct字段的ProductRelation表(这些字段可能有更好的名称)然后你知道FirstProduct与SecondProduct相关...那么你对相关产品的查询就会非常简单。

答案 3 :(得分:0)

尝试使用Acts_as_nested-plugin!

https://github.com/bbommarito/acts_as_nested_set

也许Ryan Bates的截屏视频会帮助你:

http://railscasts.com/episodes/163-self-referential-association

答案 4 :(得分:0)

我发现这个答案最有用: 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