0

私は2つのモデル:ProgramStudentとStudentCheckInを持っています(学生は多くのクラスチェックインができるので、StudentCheckInはProgramStudentに属します)。 ProgramStudentには、現在のランクに達した日時を示すdate_of_rank Date列があります。Railsでの複雑な結合

date_of_rank以降にX個以上のチェックインがあるすべてのProgramStudentsを識別するクエリを生成したいとします。

StudentCheckInモデルがこのスコープを持っています

scope :since, -> (date) { where("checked_in_at >= ?", date) } 

私は次のようにこの範囲をマージするクエリを作成することができます

次のSQL生成
ProgramStudent.joins(:student_check_ins) 
    .merge(StudentCheckIn.since(Date.today - 2.months)) 
    .group("program_students.id") 
    .having("count(*) > ?", 15) 

SELECT "program_students".* FROM "program_students" 
INNER JOIN "student_check_ins" 
ON "student_check_ins"."program_student_id" = "program_students"."id" 
WHERE (checked_in_at >= '2016-02-12') 
GROUP BY program_students.id 
HAVING count(*) > 15 

をこれは、固定日付以降15回以上のチェックインを行っているすべてのプログラム受講者を返します(このケースは2か月前です)、私はクエリに、固定された日付ではなく、個々のProgramStudentのdate_of_rankを使用するようにします。 ActiveRecordでこれを行う方法はありますか?そうでない場合、これは生のSQLでどのように行われますか?

答えて

1

これはあなたが目指しているSQLです:私は、任意の文字列の入力は、おそらくエスケープになるだろうので、あなたのsinceスコープは、列名を取ることができる疑う、しかし、あなただけでwhere句を置くことができ

SELECT "program_students".* FROM "program_students" 
INNER JOIN "student_check_ins" 
ON "student_check_ins"."program_student_id" = "program_students"."id" 
WHERE (checked_in_at >= "program_students"."date_of_rank") 
GROUP BY program_students.id, program_students.date_of_rank 
HAVING count(*) > 15 

最終ARel:

ProgramStudent.joins(:student_check_ins). 
    where("student_check_ins.checked_in_at >= program_students.date_of_rank"). 
    group("program_students.id, program_students.date_of_rank"). 
    having("count(*) > ?", 15)