I'm using a SELECT DISTINCT
and having issues trying to order my results by an associated value. Take this example (in Rails):
I have a Cook
model with a distinct customers
association:
has_many :customers, -> { distinct }, through: :orders, source: :user
It's distinct because I only want to count customers once, even if they have multiple orders.
The generated SQL for this is:
> cook.customers.to_sql
=> "SELECT DISTINCT "users".* FROM "users"
INNER JOIN "orders" ON "users"."id" = "orders"."user_id"
INNER JOIN "meals" ON "orders"."meal_id" = "meals"."id"
WHERE "meals"."cook_id" = 1"
This works fine! (the orders
table is associated through meals
but feel free to ignore)
I want to order this list of customers by the most recent created_at
value of the orders of those customers. But when I do this, I get an error:
cook.customers.order('orders.created_at DESC').to_sql
=> "SELECT DISTINCT "users".* FROM "users"
INNER JOIN "orders" ON "users"."id" = "orders"."user_id"
INNER JOIN "meals" ON "orders"."meal_id" = "meals"."id "WHERE "meals"."cook_id" = 1 ORDER BY orders.created_at DESC"
> cook.customers.order('orders.created_at DESC')
ActiveRecord::StatementInvalid: PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
LINE 1: ...eals"."id" WHERE "meals"."cook_id" = $1 ORDER BY orders.cre...
Even if I explicitly join the tables (don't think I should need to because of has_many through
), this still doesn't work.
cook.customers.joins(:orders).order('orders.created_at DESC').to_sql
=> "SELECT DISTINCT "users".* FROM "users" INNER JOIN "orders" "orders_users" ON "orders_users"."user_id" = "users"."id" INNER JOIN "orders" ON "users"."id" = "orders"."user_id" INNER JOIN "meals" ON "orders"."meal_id" = "meals"."id" WHERE "meals"."cook_id" = 1 ORDER BY orders.created_at DESC"
Any clues? I'm looking for a solution that will return an ActiveRecord relation (so no using sort_by
), because I plan on chaining additional queries to this.
Thank you :)
Aucun commentaire:
Enregistrer un commentaire