Student and Parent have a has_and_belongs_to_many
relationship, both belong to a School.
This query returns the latest timestamp:
School.first.students.includes(:parents).maximum("parents.updated_at")
Why doesn't this:
School.first.students.left_outer_joins(:parents).select("MAX(parents.updated_at)")
The console log implies that both execute the same SQL:
SELECT MAX(parents.updated_at) FROM "students" LEFT OUTER JOIN "parents_students" ON "parents_students"."student_id" = "students"."id" LEFT OUTER JOIN "parents" ON "parents"."id" = "parents_students"."parent_id" WHERE "students"."school_id" = $1 [["school_id", 1]]
But the first is the only one that returns a timestamp value.
The reason I want to use the 2nd form is that I'd like to be able to do things like:
School.first.students.left_outer_joins(:parents).select('COUNT(students.*) AS student_count, COUNT(parents.*) AS parent_count, MAX(students.updated_at) AS student_latest_update, MAX(parents.updated_at) AS parent_latest_update')`<br>
to compute a cache key for a view with associations. I'm currently using an inefficient array key that performs redundant queries:
<% cache [batch_of_students, batch_of_students.includes(:parents).maximum("parents.updated_at")] do %>
You can do it with pluck.
School.first.students.left_outer_joins(:parents).pluck("MAX(parents.updated_at)")
You can then create your cache_key with
cache_key = School.first.students.left_outer_joins(:parents)
.pluck(%(
COUNT(students.*),
COUNT(parents.*),
MAX(students.updated_at),
MAX(parents.updated_at)))
Which returns an array with those 4 values which can act as your cache key.
# [100, 100, 2015-08-24 02:14:07 UTC, 2015-08-24 02:14:07 UTC]