私の目標は、Member
オブジェクトの完成したすべてのコースを見ることができる範囲を作ることです。複雑なRails has_manyスコープで外部結合を作成するにはどうすればよいですか?
Course
は多くのSections
で構成されています。 Section
にはQuiz
が1つあります。 Course
が完了するためには、すべてのQuiz
をcomplete
に設定する必要があります。例えば
:私は欠けている部分が実際にSQLではありませんこの部分count(sections.quizzes.id)
ある
# Member.rb
has_many :completed_courses, -> {
joins(:quizzes, :sections)
.where(quizzes: {completed: true})
.group('members.id HAVING count(sections.quizzes.id) = count(sections.id)')
}, through: :course_members, source: :course
:
Course
Section A -> Quiz A (Complete)
Section B -> Quiz B (Complete)
Section C -> Quiz C (Complete)
これはスコープのこの種の書き込みで私の最高の試みであります。どのような種類のJOIN
が呼び出されるのかは完全にはわかりませんが、count
のコースに所属する完成したクイズをいくつかのセクションと比較する必要があります。それらが等しい場合、それはすべてのクイズが完了したことを意味します。
このようなJOINの名前を知っているだけで、私は正しい方向に向かうでしょう。
更新
私はの応答@jamesdevar使用してみました:
has_many :completed_courses, -> {
joins(:sections)
.joins('LEFT JOIN quizzes ON quizzes.section_id = sections.id')
.having('COUNT(sections.id) = SUM(CASE WHEN quizzes.completed = true THEN 1 ELSE 0 END)')
.group('courses.id')
}, through: :course_members, source: :course
をしかし、とき、それはいけない、それは[ ]
値を返します。たとえば、私はこのデータを持っています:
-> Course{id: 1}
-> Section{id: 1, course_id: 1}
-> Quiz{section_id: 1, member_id: 1, completed: true}
コースは合計で1セクションです。セクションには、他のメンバーから数百のクイズが関連付けられている場合がありますが、この特定のメンバーのクイズは完了しています。
私は、このSQLの比較が個々のメンバーに固有のものではないと考えています。
.having('COUNT(sections.id) = SUM(CASE WHEN quizzes.completed = true THEN 1 ELSE 0 END)')
生成される実際のSQLはこれです:各セクションは、クイズを完了したときhaving
条件によって各cources.id
グループをフィルタリングします。この場合
SELECT "courses".* FROM "courses"
INNER JOIN "sections" ON "sections"."course_id" = "courses"."id"
INNER JOIN "course_members" ON "courses"."id" = "course_members"."course_id"
LEFT JOIN quizzes ON quizzes.section_id = sections.id
WHERE "course_members"."member_id" = $1
GROUP BY courses.id
HAVING COUNT(sections.id) = SUM(CASE WHEN quizzes.completed = true THEN 1 ELSE 0 END)
ORDER BY "courses"."title"
ASC [["member_id", 1121230]]
これは本当に素晴らしいです、ありがとうございます。すべてのクイズが完了しても常に[]を返すので正確には機能しません。上記で例を挙げて更新します。 – Trip
Woopsは、すべてのことを考え出しました(これは、私があなたに話していなかった他の属性と関連していました)。手伝ってくれてどうもありがとう!あなたは私を完全に解決するのを助けました。本当にありがとう! – Trip