[英]Eager load Rails' has_many with two primary_keys and foreign_keys
我有兩個模型
class TimeEntry < ApplicationRecord
belongs_to :contract
end
class Timesheet < ApplicationRecord
belongs_to :contract
has_many :time_entries, primary_key: :contract_id, foreign_key: :contract_id
end
此外,兩種型號都有date
欄。
問題: Timesheet
僅適用於固定日期,並且通過僅限於contract_id
的范圍,我總是獲得每個Timesheet
的合同的所有time_entries
。
我試過 scope 是這樣的:
has_many :time_entries, ->(sheet) { where(date: sheet.date) }, primary_key: :contract_id, foreign_key: :contract_id
這行得通,但不幸的是它不是急切可加載的:
irb(main):019:0> Timesheet.where(id: [1,2,3]).includes(:time_entries).to_a
Timesheet Load (117.9ms) SELECT "timesheets".* FROM "timesheets" WHERE "timesheets"."id" IN ($1, $2, $3) [["id", 1], ["id", 2], ["id", 3]]
TimeEntry Load (0.3ms) SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."date" = $1 AND "time_entries"."contract_id" = $2 [["date", "2014-11-21"], ["contract_id", 1]]
TimeEntry Load (0.3ms) SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."date" = $1 AND "time_entries"."contract_id" = $2 [["date", "2014-11-22"], ["contract_id", 1]]
TimeEntry Load (0.3ms) SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."date" = $1 AND "time_entries"."contract_id" = $2 [["date", "2014-11-23"], ["contract_id", 1]]
是否有可能為 Rails 提供兩個主鍵和外鍵? 或者我怎樣才能使上面的示例易於加載以避免 n+1 查詢?
您可以對關聯使用自定義 SQL 查詢,以這種方式檢索給定Timesheet
的TimeEntry
記錄:
class Timesheet < ApplicationRecord
belongs_to :contract
has_many :time_entries, lambda {
select('*')
.from('time_entries')
.where('time_entries.date = timesheets.date')
.where('time_entries.contract_id = timesheets.contract_id')
}, primary_key: :contract_id, foreign_key: :contract_id
end
然后,可以使用
timesheets = Timesheet.where(id: [1,2,3]).eager_load(:time_entries)
time_entries = timesheets.first.time_entries
注意:- 這僅適用於預加載,不適用於預加載。 這就是明確使用關鍵字而不是包含的原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.