假设我有一个表products
并希望为每个产品维护similar_products
。
这是自引用表的迁移。
create_table :similar_products, id: false do |t|
t.references :product, foreign_key: true, null: false
t.references :similar_product, foreign_key: { to_table: :similar_products }
end
class SimilarProductRelation < ApplicationRecord
belongs_to :product
belongs_to :similar_product, class_name: "Product"
end
class Product < ApplicationRecord
# self being the "origin"
has_many :similar_products_relations, source: :product_id, class_name: "SimilarProductRelation"
has_many :similar_products, class_name: "Product", through: :similar_products_relations
# self being the "destination"
has_many :similar_products_relations_as, source: :similar_product_id, class_name: "SimilarProductRelation"
has_many :similar_products_as, class_name: "Product", through: :similar_products_relations
end
# migration
create_table :similar_product_relations do |t|
t.references :product, foreign_key: true, null: false, index: true
t.references :similar_product, foreign_key: { to_table: :products }, null: false, index: true
end
索引是否为真取决于要进行查询的方向,并且如果您只打算使用一个方向,则只能在关联中保留一个方向,即Product
类中。
您可以尝试以下方法:
class Product < ActiveRecord::Base
belongs_to :product, :class_name => 'Product'
has_many :similar_products, :class_name => 'Product', :foreign_key => 'parent_id'
end
迁移可以添加为:
add_column :products, :parent_id, :integer, null: true, index: true
add_foreign_key :products, :products, column: :parent_id