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

时间:2022-10-04 15:33:01

I'm working on a Rails app that has a "products" model. I want to be able to relate products to each other. Example: product 1 related to product 2, product 3, and vice versa. How would I accomplish this in Rails? I was thinking a join table, but since I'm using the same table as the point-of-relationship I'm not sure how that would work.

我正在开发一个Rails应用程序,它有一个“产品”模型。我想把产品联系起来。例:产品1与产品2、产品3相关,反之亦然。如何在Rails中实现这一点?我想要一个连接表,但是由于我使用的是与关系点相同的表,所以我不确定它是如何工作的。

5 个解决方案

#1


3  

Untested and from memory, I think you'd want something like this:

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

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 (or whatever you'd choose to call it) would then be able to contain one or more additional fields that describe the relationship.

ProductLink(或者您选择调用它的任何东西)将能够包含一个或多个描述该关系的额外字段。

You may be able to make it work with has_and_belongs_to_many, although I guess this would require a "products_products" table, which might be a little stressful.

您可能可以使用has_and_belongs_to_many来实现它,尽管我认为这需要一个“products_products”表,这可能会有一点压力。

#2


1  

Use the acts_as_follower gem. http://github.com/tcocca/acts_as_follower/tree/master. It is pretty flexible in terms of following relationships and provides a generic following semantics.

使用acts_as_follower宝石。http://github.com/tcocca/acts_as_follower/tree/master。它在跟踪关系方面相当灵活,并提供了一个通用的以下语义。

Really simple, and works very well. Just use it to say product 1 follows product 2/3 etc.

非常简单,而且效果很好。用它来表示产品1跟随产品2/3等等。

#3


0  

You are right, you need a join table. It needs two fields, both of which are foreign keys back to the products table.

您是对的,您需要一个连接表。它需要两个字段,这两个字段都是返回到product表的外键。

So something like ProductRelation table with FirstProduct and SecondProduct fields (there probably is better names for those fields) then you know that FirstProduct is related to SecondProduct... then your queries for related products would be pretty simple.

比如product关联表,FirstProduct和SecondProduct字段(这些字段可能有更好的名称)那么你就知道FirstProduct与SecondProduct相关。那么您对相关产品的查询将非常简单。

#4


0  

Try the Acts_as_nested-plugin!

尝试Acts_as_nested-plugin !

https://github.com/bbommarito/acts_as_nested_set

https://github.com/bbommarito/acts_as_nested_set

Maybe also Ryan Bates screencasts helps you:

也许瑞恩·贝茨的演讲也能帮助你:

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

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

#5


0  

I found this answer the most useful: Ruby On Rails - many to many between the same table

我发现这个答案最有用:Ruby On Rails——很多很多人都在同一个表之间

From this, I successfully implemented a bi-directional many-to-many association of a model to itself. In your case, it will be as follows:

从此,我成功地实现了一个模型的双向多对多关联。在你的情况下,将如下:

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

#1


3  

Untested and from memory, I think you'd want something like this:

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

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 (or whatever you'd choose to call it) would then be able to contain one or more additional fields that describe the relationship.

ProductLink(或者您选择调用它的任何东西)将能够包含一个或多个描述该关系的额外字段。

You may be able to make it work with has_and_belongs_to_many, although I guess this would require a "products_products" table, which might be a little stressful.

您可能可以使用has_and_belongs_to_many来实现它,尽管我认为这需要一个“products_products”表,这可能会有一点压力。

#2


1  

Use the acts_as_follower gem. http://github.com/tcocca/acts_as_follower/tree/master. It is pretty flexible in terms of following relationships and provides a generic following semantics.

使用acts_as_follower宝石。http://github.com/tcocca/acts_as_follower/tree/master。它在跟踪关系方面相当灵活,并提供了一个通用的以下语义。

Really simple, and works very well. Just use it to say product 1 follows product 2/3 etc.

非常简单,而且效果很好。用它来表示产品1跟随产品2/3等等。

#3


0  

You are right, you need a join table. It needs two fields, both of which are foreign keys back to the products table.

您是对的,您需要一个连接表。它需要两个字段,这两个字段都是返回到product表的外键。

So something like ProductRelation table with FirstProduct and SecondProduct fields (there probably is better names for those fields) then you know that FirstProduct is related to SecondProduct... then your queries for related products would be pretty simple.

比如product关联表,FirstProduct和SecondProduct字段(这些字段可能有更好的名称)那么你就知道FirstProduct与SecondProduct相关。那么您对相关产品的查询将非常简单。

#4


0  

Try the Acts_as_nested-plugin!

尝试Acts_as_nested-plugin !

https://github.com/bbommarito/acts_as_nested_set

https://github.com/bbommarito/acts_as_nested_set

Maybe also Ryan Bates screencasts helps you:

也许瑞恩·贝茨的演讲也能帮助你:

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

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

#5


0  

I found this answer the most useful: Ruby On Rails - many to many between the same table

我发现这个答案最有用:Ruby On Rails——很多很多人都在同一个表之间

From this, I successfully implemented a bi-directional many-to-many association of a model to itself. In your case, it will be as follows:

从此,我成功地实现了一个模型的双向多对多关联。在你的情况下,将如下:

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