I have a Department model with two associations to User such that
class Department < ActiveRecord::Base
has_many :members, class_name:"User", foreign_key:"department_id"
belongs_to :director, class_name:"User", foreign_key:"director_id
end
To display this model in a listing, sorted by number of members I can do this
@departments = Department.select("departments.*, COUNT(users.id) AS members").joins(:members).group("departments.id")
@departments = @departments.order("members ASC")
If I wanted to sort by a field (last_name) in the director’s associated model, I could do this:
@departments = Department.includes(:director)
@departments = @departments.order("users.last_name")
However, I can’t combine these two queries into one that allows correct sorting of both. If I do
Department.select("departments.*, COUNT(users.id) AS members").joins(:members, :director).group("departments.id, users.last_name")
then I get a vast ammount of duplicate results, and I also exclude resuls where director_id is nil. How can I structure the query so that I can order by both COUNT(users.id) and essentially director.last_name ?
Edit: This is the .to_sql for that bad combined query:
SELECT departments.*, COUNT(users.id) AS members FROM "departments"
INNER JOIN "users" ON "users"."department_id" = "departments"."id"
INNER JOIN "users" "directors_departments"
ON "directors_departments"."id" = "departments"."director_id"
GROUP BY departments.id, users.last_name
ORDER BY users.last_name DESC
So there are 2 problems here:
.joinson abelongs_toassociation that may not exist.Solution:
You’ll need a LEFT JOIN which unfortunately isn’t as pretty as a standard join. You’ll also need to modify your
.groupclause: