ruby-on-rails - 如何在复杂的 Rails has_many 作用域中进行外部连接?

标签 ruby-on-rails postgresql join scope psql

我的目标是创建一个范围,我可以在其中查看Member 对象的所有已完成类(class)。

Course 由许多Sections 组成。每个部分有一个测验。并且每个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,但我需要一些方法来计算属于类(class)的已完成测验并将该数字与如何进行比较许多部分。如果它们相等,则表示所有测验都已完成。

公平地说,只要知道这种 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}

类(class)一共一个Section。该部分可能有数百个来自其他成员的与之相关的测验,但对于这个特定的成员,他的测验已经完成。

我认为这与此 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

在这种情况下,having 将在每个部分完成测验时按条件过滤每个 cources.id 组。

关于ruby-on-rails - 如何在复杂的 Rails has_many 作用域中进行外部连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47876938/

相关文章:

mysql - ON 子句中的额外条件被忽略

mysql - 合并同一个表中的 2 个字段?

ruby-on-rails - 如何在 Windows PC(Windows 7/Windows 8)上部署 Rails 应用程序?

postgresql - 默认情况下以只读事务启动 psql

ruby-on-rails - 即将创建我自己的网上商店?优点和缺点

postgresql - 使用 Talend 将 yyyyMMdd 字符串插入日期列

java - 无法使用 LIKE 从 PostgreSQL 选择 Unicode 数据

mysql - 将表 1(外键)中的 2 列连接到表 2(主键) - 如何避免 JOIN BUFFER?

ruby-on-rails - 如何插入可预测的 ID 以使用 ActiveRecord 进行测试

ruby-on-rails - 一个大型 Rails 应用程序与单独的应用程序