简体   繁体   中英

ActiveRecord has_one with order by date

I'm trying to set up an ActiveRecord relationship where I have a has_one that returns the most recent value:

class Check < ApplicationRecord
  has_many :counts
  has_one :latest_count, -> { order(created_at: :desc) }, class_name: 'Count'
end

The reason for wanting it this way is to avoid N+1 queries when looking up the latest_count :

current_user.checks.preload(:latest_count)

The problem I'm running into is that preloading latest_count actually preloads all of the counts and grabs the last one in memory. Even at a small scale this is turning out to cause issues, with both memory bloat and query times increasing very quickly. Is there any way to set this relationship up so that it only preloads the last one? The only alternative that comes to mind for me is to add a latest_count_id to the checks table and update that whenever a new count is created.

Update latest_count_id when a new count is created doesn't seem to be efficient.

You could try a custom SELECT like this:

# Example code, may need to tweak a bit

class Check
  scope :preload_latest_count, -> {
    joins.lfet_joins(:counts)
         .order("checks.id, counts.created_at DESC")
         .select("DISTINCT ON (checks.id) checks.*, counts.value AS latest_count_value")
  }
end

checks = current.checks.preload_latest_count
check = checks.first
check.latest_count_value

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM