Like in this question I am looking to eager load another object and then sort the list based on a value from the eager loaded object.
Given parent Foo
and child Bar
:
class Foo < ActiveRecord::Base
has_many :bar, foreign_key: :foo_name, primary_key: :name
has_one :most_recent_bar, -> { order created at desc }, foreign_key: :foo_name, primary_key: :name
end
class Bar < ActiveRecord::Base
belongs_to :foo, foreign_key: :foo_name, primary_key: :name
end
I am looking to show a list of Foo
s, and then sort them by Bar.value
and Foo.name
. I am only looking for the most recently created Bar
, so it's sorted in reverse order and limited to 1. So:
@foos = Foo.includes(:most_recent_bar).order('bar.value asc, foo.name asc')
The problem: The order statement above is changing most_recent_bar
. It is ordering all Foo.bars
and then picking the most recent of the sorted list. It is only then ordering the list by Foo.name
.
The Question: How can I appropriately order these eager loaded values such that most_recent_bar
is legitimately the most recently created, and then order the list of Foo
s based on most_recent_bar.value
?
Edit for SQL from my live code:
Foo.includes(:most_recent_bar).order('bars.value asc, name asc')
SQL (7.9ms) SELECT "foos"."id" AS t0_r0, "foos"."name" AS t0_r1, "foos"."created_at" AS t0_r2, "foos"."updated_at" AS t0_r3, "bars"."id" AS t1_r0, "bars"."content" AS t1_r1, "bars"."created_at" AS t1_r2, "bars"."updated_at" AS t1_r3, "bars"."foo_name" AS t1_r4, "bars"."version" AS t1_r5, "bars"."bbj_status" AS t1_r6, "bars"."host" AS t1_r7, "bars"."value" AS t1_r8 FROM "foos" LEFT OUTER JOIN "bars" ON "bars"."foo_name" = "foos"."name" ORDER BY bars.value asc, name asc
Edit for broken SQL after fix Seems to be looking for two created ats, and I'm not sure where the ambiguous one is coming from!
My error SQL Foo.includes(:most_recent_foo).merge(bar.most_recent).order('bars.repo asc')
SQL (0.6ms) SELECT "foos"."id" AS t0_r0, "foos"."name" AS t0_r1, "foos"."created_at" AS t0_r2, "foos"."updated_at" AS t0_r3, "bars"."id" AS t1_r0, "bars"."content" AS t1_r1, "bars"."created_at" AS t1_r2, "bars"."updated_at" AS t1_r3, "bars"."foo_name" AS t1_r4, "bars"."version" AS t1_r5, "bars"."bbj_status" AS t1_r6, "bars"."host" AS t1_r7, "bars"."repo" AS t1_r8 FROM "foos" LEFT OUTER JOIN "bars" ON "bars"."foo_name" = "foos"."name" ORDER BY created_at DESC, bars.created_at desc, bars.repo asc
PG::Error: ERROR: column reference "created_at" is ambiguous
LINE 1: …bars”.”foo_name" = "foos"."name" ORDER BY created_at...