我有两个模型StageBatch
和StageItem
:
class StageItem < ApplicationRecord
has_and_belongs_to_many :stage_batches
end
class StageBatch < ApplicationRecord
has_and_belongs_to_many :stage_items
end
通过以下迁移:
class CreateStageBatchesAndStageItems < ActiveRecord::Migration[5.0]
def change
create_table :stage_items do |t|
t.string :name
t.timestamps
end
create_table :stage_batches do |t|
t.timestamps
end
create_table :stage_batches_and_stage_items, id: false do |t|
t.belongs_to :stage_item, index: true
t.belongs_to :stage_batch, index: true
end
end
end
当我尝试访问stage_batches
stage_items
时,出现以下错误:
irb(main):002:0> StageBatch.first.stage_items
StageBatch Load (0.2ms) SELECT "stage_batches".* FROM "stage_batches" ORDER BY "stage_batches"."id" ASC LIMIT ? [["LIMIT", 1]]
StageItem Load (0.4ms) SELECT "stage_items".* FROM "stage_items" INNER JOIN "stage_batches_items" ON "stage_items"."id" = "stage_batches_items"."stage_item_id" WHERE "stage_batches_items"."stage_batch_id" = ? [["stage_batch_id", 1]]
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such table: stage_batches_items: SELECT "stage_items".* FROM "stage_items" INNER JOIN "stage_batches_items" ON "stage_items"."id" = "stage_batches_items"."stage_item_id" WHERE "stage_batches_items"."stage_batch_id" = ?
stage_batches_and_stage_items
变为`
我的迁移有问题吗?stage_batches_and_stage_items
更改为stage_batches_items
?答案 0 :(得分:0)
在使用has_and_belongs_to_many
时,您必须遵循Rails命名约定来命名连接表。或者,您可以使用join_table
选项指定连接表名称。
在您的特定情况下,将stage_batches_and_stage_items
的名称更改为stage_batches_stage_items
。默认情况下,连接表以词法顺序具有两个表名(复数形式)。
来自Rails guide [Section 3.3.2]:
如果您创建了has_and_belongs_to_many关联,则需要 显式创建连接表。除非连接表的名称 通过使用:join_table选项Active Record明确指定 通过使用类名的词汇书来创建名称。那么一个 作者和书籍模型之间的连接将给出默认的连接表 &#34; authors_books&#34;的名称因为&#34; a&#34;超支&#34; b&#34;在词汇排序中。
如果由于它的限制(例如,您无法在此加入表中添加任何额外的列),我建议避免使用has_and_belongs_to_many
(如果这不是一个严格的要求)。相反,请使用{ {3}}关联。在这种情况下,您可以轻松自定义连接的表名称。此外,您可以根据需要在连接表中添加额外的列。
以下是使用has_many :through
关联代码的方式:
class StageItem < ApplicationRecord
has_many :stage_item_batches
has_many :stage_batches, through: :stage_item_batches
end
# joining model
class StageItemBatch < ApplicationRecord
belongs_to :stage_item
belongs_to :stage_batch
end
class StageBatch < ApplicationRecord
has_many :stage_item_batches
has_many :stage_items, through: :stage_item_batches
end
原始两个模型的迁移将保持不变。您只需要迁移加入模型:
rails g model StageItemBatch stage_item:references stage_batch:references