如何在复杂的Rails has_many范围内进行外连接?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在复杂的Rails has_many范围内进行外连接?相关的知识,希望对你有一定的参考价值。
我的目标是建立一个范围,我可以看到所有已完成的Member
对象的课程。
Course
由许多Sections
组成。每个Quiz
有一个Section
。每一个Quiz
都必须设置为complete
才能使Course
完整。
例如 :
Course
Section A -> Quiz A ( Complete )
Section B -> Quiz B ( Complete )
Section C -> Quiz C ( Complete )
这是我写这种范围的最佳尝试:
# 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
我缺少的部分是这部分count(sections.quizzes.id)
,它实际上不是SQL。我不完全确定这会被称为什么样的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}
该课程共有一个科。该科可能有数百个与其他会员相关的测验,但对于这个特定的会员,他的测验已经完成。
我认为它与这个SQL比较有关,而不是单个成员所独有的。
.having('COUNT(sections.id) = SUM(CASE WHEN quizzes.completed = true THEN 1 ELSE 0 END)')
生成的实际SQL是这样的:
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]]
答案
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
在这种情况下,当每个部分完成quizz时,having
将按条件过滤每个cources.id
组。
以上是关于如何在复杂的Rails has_many范围内进行外连接?的主要内容,如果未能解决你的问题,请参考以下文章
has_many 中 :unique => true/Distinct 选项的问题,通过关联/命名范围(Rails)