我創建了一個專案表和一個作業表。然后,我創建了一個連接表 Items Jobs。
這是我對連接表和模型的遷移:
class CreateItemsJobs < ActiveRecord::Migration[7.0]
def change
create_table :items_jobs, id: false do |t|
t.belongs_to :item
t.belongs_to :job
t.timestamps
end
end
end
class Item < ApplicationRecord
belongs_to :part
belongs_to :employee, optional: true
has_and_belongs_to_many :jobs
end
class Job < ApplicationRecord
belongs_to :client
belongs_to :employee
has_and_belongs_to_many :items
end
class ItemsJobs < ApplicationRecord
belongs_to :item
belongs_to :job
end
然后我成功遷移...
rails db:migrate ==>
== 20220210032352 CreateItemsJobs: migrating ==================================
-- create_table(:items_jobs, {:id=>false})
-> 0.0085s
== 20220210032352 CreateItemsJobs: migrated (0.0086s) =========================
但是,如果我嘗試播種,則會出現錯誤。如果我運行我的 rails 控制臺,我無法添加到表中,直到我嘗試查看一個不存在的表。
rails c ==>
Loading development environment (Rails 7.0.1)
2.7.4 :001 > ItemsJobs.all
Traceback (most recent call last):
(irb):1:in `<main>': uninitialized constant ItemsJobs (NameError)
Did you mean? ItemJob
2.7.4 :002 > ItemJob.all
Traceback (most recent call last):
(irb):2:in `<main>': uninitialized constant ItemJob (NameError)
Did you mean? ItemsJobs
2.7.4 :003 > ItemsJobs.all
ItemsJobs Load (0.4ms) SELECT "items_jobs".* FROM "items_jobs"
=> []
2.7.4 :004 > ItemsJobs.create(item_id: 1, job_id: 1)
TRANSACTION (0.2ms) BEGIN1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Job Load (0.3ms) SELECT "jobs".* FROM "jobs" WHERE "jobs"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
ItemsJobs Create (0.6ms) INSERT INTO "items_jobs" ("item_id", "job_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) [["item_id", 1], ["job_id", 1], ["created_at", "2022-02-10 15:23:44.127164"], ["updated_at", "2022-02-10 15:23:44.127164"]]
TRANSACTION (1.1ms) COMMIT
=>
#<ItemsJobs:0x00007f33c0aa7a80
item_id: 1,
job_id: 1,
created_at: Thu, 10 Feb 2022 15:23:44.127164000 UTC 00:00,
updated_at: Thu, 10 Feb 2022 15:23:44.127164000 UTC 00:00>
這里出了什么問題?為什么我無法查看/添加到 ItemsJobs 表,直到我嘗試查看建議的、不存在的 ItemJob 表?
uj5u.com熱心網友回復:
你搞混了has_and_belongs_to_many,has_many through:奇怪的自動加載行為很可能是因為命名方案拋棄了 ActiveRecord 如何通過約定優于配置將類映射到資料庫表。經驗法則是 ActiveRecord 期望模型(類名)是單數,表是復數。
HABTM 關聯不使用連接表的模型。相反,它只是一個“無頭”關聯,您只需通過每一端的關聯隱式添加/洗掉行。HABTM 僅適用于您知道不需要直接查詢表或訪問任何其他列的情況 - 換句話說,它在該利基之外毫無用處。HABTM 是 ActiveRecord 中唯一使用plural_plural表命名方案的地方 - 使用該方案和模型將導致不斷的查找錯誤,除非您明確配置所有內容。
如果您想使用連接模型設定關聯(我建議這樣做),您需要正確命名類和表并使用間接關聯:
class CreateItemJobs < ActiveRecord::Migration[7.0]
def change
# table name should be singular_plural
create_table :item_jobs do |t|
t.belongs_to :item
t.belongs_to :job
t.timestamps
end
end
end
# model class names should always be singular
class ItemJob < ApplicationRecord
belongs_to :item
belongs_to :job
end
class Item < ApplicationRecord
belongs_to :part
belongs_to :employee, optional: true
has_many :item_jobs
has_many :jobs, through: :item_jobs
end
class Job < ApplicationRecord
belongs_to :client
belongs_to :employee
has_many :item_jobs
has_many :items, through: :item_jobs
end
由于您可能沒有在生產中運行遷移并且表中沒有任何有意義的資料,您可以回滾錯誤的CreateItemsJobs遷移并將其洗掉。rails g model ItemJob item:belongs_to job:belongs_to將創建模型和遷移。
看:
- https://guides.rubyonrails.org/active_record_basics.html#convention-over-configuration-in-active-record
- https://guides.rubyonrails.org/association_basics.html#the-has-many-through-association
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/428236.html
