2

Departmentユーザーとの関連付けが2つあるモデルがあります。

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

このモデルをメンバー数でソートしたリストに表示するには、これを行うことができます

@departments = Department.select("departments.*, COUNT(users.id) AS members").joins(:members).group("departments.id")
@departments = @departments.order("members ASC")

ディレクターに関連付けられたモデルのフィールド()で並べ替える場合はlast_name、次のように実行できます。

@departments = Department.includes(:director)
@departments = @departments.order("users.last_name")

ただし、これら2つのクエリを組み合わせて、両方を正しく並べ替えることができるようにすることはできません。私が行った場合

Department.select("departments.*, COUNT(users.id) AS members").joins(:members, :director).group("departments.id, users.last_name")

次に、膨大な量の重複した結果が得られます。また、director_idがnilの場合の結果も除外します。COUNT(users.id)クエリを構造化して、基本的に両方で注文できるようにするにはどうすればよいdirector.last_nameですか?

編集:これは.to_sqlその悪い結合されたクエリのためのものです:

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
4

1 に答える 1

4

したがって、ここには2つの問題があります:

  1. 存在しない可能性のある関連付けで使用.joinsしています。belongs_to
  2. 同じユーザー テーブルを 2 回 (2 つの異なる関連付けのために) 結合しているため、Rails がテーブル エイリアスを生成して、SQL が有効になります。しかし、このエイリアスでグループ化していません。

解決:

残念ながら、標準の結合ほどきれいではない LEFT JOIN が必要です。.groupまた、句を変更する必要があります。

Department.
  select("departments.*, COUNT(users.id) AS members").
  joins(:members, "LEFT JOIN users directors ON departments.director_id = directors.id").
  group("departments.id, directors.last_name").
  order("members, directors.last_name")
于 2012-12-03T21:40:23.960 に答える