簡體   English   中英

急切加載 Rails 的 has_many 有兩個主鍵和外鍵

[英]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 查詢,以這種方式檢索給定TimesheetTimeEntry記錄:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM