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.