Соотношение «многие ко многим» с одной и той же таблицей (Ruby on Rails) - PullRequest
3 голосов
/ 12 июня 2009

Я работаю над приложением Rails, которое имеет модель "products". Я хочу иметь возможность связывать продукты друг с другом. Пример: продукт 1 относится к продукту 2, продукт 3 и наоборот. Как бы я сделал это в Rails? Я думал о соединительной таблице, но поскольку я использую ту же таблицу, что и точка связи, я не уверен, как это будет работать.

Ответы [ 5 ]

3 голосов
/ 12 июня 2009

Не проверено и по памяти, я думаю, вы хотели бы что-то вроде этого:

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 голос
/ 12 июня 2009

Используйте камень acts_as_follower. http://github.com/tcocca/acts_as_follower/tree/master. Он довольно гибкий с точки зрения следующих отношений и предоставляет общую следующую семантику.

Действительно просто и работает очень хорошо. Просто используйте это, чтобы сказать, что продукт 1 следует за продуктом 2/3 и т. Д.

0 голосов
/ 12 марта 2014

Я нашел этот ответ наиболее полезным: Ruby On Rails - много ко многим между одной и той же таблицей

Исходя из этого, я успешно реализовал двунаправленную связь модели «многие ко многим» с самим собой. В вашем случае это будет выглядеть так:

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
0 голосов
/ 12 июня 2009

Попробуйте подключаемый модуль Acts_as_nested!

https://github.com/bbommarito/acts_as_nested_set

Может быть, вам также помогут скриншоты Райана Бейтса:

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

0 голосов
/ 12 июня 2009

Вы правы, вам нужен объединительный стол. Требуются два поля, оба из которых являются внешними ключами обратно в таблицу продуктов.

Итак, что-то вроде таблицы ProductRelation с полями FirstProduct и SecondProduct (вероятно, есть более подходящие имена для этих полей), тогда вы знаете, что FirstProduct связан со SecondProduct ... тогда ваши запросы для связанных продуктов будут довольно простыми.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...