我不确定在您的情况下是否可以将has_many 自动添加到模型中,在这种情况下我手动添加它。
运行 rails g migration CreateJoinTableRecordProductsShopyTagProducts record_products:references:index shopi_tag_products:references:index
将生成此迁移:
class CreateJoinTableRecordProductsShopyTagProducts < ActiveRecord::Migration[5.2]
def change
create_join_table :record_products, :shopi_tag_products do |t|
t.references :record_products, foreign_key: true
t.references :shopi_tag_products, foreign_key: true
end
end
end
t.references 在这里是多余的,因为您已经使用了create_join_table
rails g migration CreateJoinTableRecordProductsShopyTagProducts record_products shopi_tag_products 将完成这项工作。
它会生成这样的文件:
class CreateJoinTableRecordProductsShopyTagProducts < ActiveRecord::Migration[5.2]
def change
create_join_table :record_products, :shopi_tag_products do |t|
# t.index [:record_product_id, :shopi_tag_product_id]
# t.index [:shopi_tag_product_id, :record_product_id]
end
end
end
您需要取消注释索引并为其分配名称以解决索引名称过长的问题。
作为替代方案,您可以这样:
rails g model record_products_shopi_tag_products record_product:references shopi_tag_product:references
它将生成:
class CreateRecordProductsShopiTagProducts < ActiveRecord::Migration[5.2]
def change
create_table :record_products_shopi_tag_products do |t|
t.references :record_product, foreign_key: true
t.references :shopi_tag_product, foreign_key: true
t.timestamps
end
end
end
注意这里用create_table代替create_join_table,所以在这种情况下你必须写t.references。
在此迁移中,您必须添加 , index: {name: ...} 以解决长索引问题。
我写过这样的模型:
rails g model RecordProduct name:string
rails g model ShopiTagProduct name:string
record_product.rb
class RecordProduct < ApplicationRecord
# has_and_belongs_to_many :shopi_tag_products
# not needed if you use has_and_belongs_to_many
has_many :record_products_shopi_tag_products, dependent: :destroy
has_many :shopi_tag_products, through: :record_products_shopi_tag_products
validates :name, presence: true
end
shopi_tag_product.rb
class ShopiTagProduct < ApplicationRecord
# has_and_belongs_to_many :record_products
# not needed if you use has_and_belongs_to_many
has_many :record_products_shopi_tag_products, dependent: :destroy
has_many :record_products, through: :record_products_shopi_tag_products
validates :name, presence: true
end
record_products_shopi_tag_product.rb(如果您使用 has_and_belongs_to_many,则不需要)
class RecordProductsShopiTagProduct < ApplicationRecord
belongs_to :record_product
belongs_to :shopi_tag_product
end
种子.rb
RecordProduct.destroy_all
ShopiTagProduct.destroy_all
r = RecordProduct.create!(name: 'foo')
s = ShopiTagProduct.create!(name: 'bar')
r.shopi_tag_products << s
r.save!
p ActiveRecord::Base.connection.execute('select * from record_products_shopi_tag_products')
$ rake db:seed
[{"record_product_id"=>4, "shopi_tag_product_id"=>4}]
我强烈建议使用has_many through 而不是has_and_belongs_to_many,因为has_and_belongs_to_many 不支持dependent: destroy
(habtm relationship does not support :dependent option)