Как написать SQL-запрос Rails для поиска объекта, в котором все дочерние элементы имеют одинаковое значение

Я читал это, но не имеет смысла записывать это в область видимости Rails:

найти все родительские записи, где все дочерние записи имеют заданное значение (но не только некоторые дочерние записи)

у меня есть Course, Section, а также Quiz, объект:

class Course < ActiveRecord::Base
  has_many :course_members
  has_many :members, through: :course_members
  has_many :sections
  has_many :quizzes, through: :sections
end

class Quiz < ActiveRecord::Base
  belongs_to :member
  belongs_to :section
end

class Section < ActiveRecord::Base
  belongs_to :course
  has_many :quizzes
end

Я хотел бы найти все курсы участника, где все тесты, связанные с этим курсом, имеют атрибут completed = true,

Так по моему Member класс, я в идеале хотел бы написать что-то вроде:

has_many :completed_courses, -> { 
   joins(:courses, :quizzes, :sections)
   # .select( 'CASE WHEN quizzes.completed = true then 1 end') ??? maybe ???
}, class_name: 'Course'

Ха-ха! Но за исключением того, что это слишком сложно. Я пытался написать это просто в Course также было бы хорошо.

1 ответ

Решение
class Member < ActiveRecord::Base
  has_many :courses, through: :course_members
  has_many :course_members

  has_many :completed_courses,
    -> { joins(:quizzes).where.not(quizzes: {completed: [false, nil]}) },
    through: :course_members,
    source: :course
end

Если твой completed логический столбец NOT NULL затем поменяй [false, nil] выше просто false

Пример использования

irb(main):002:0> Member.first.completed_courses
  Member Load (0.2ms)  SELECT "members".* FROM "members" ORDER BY "members"."id" ASC LIMIT 1
  Course Load (0.1ms)  SELECT "courses".* FROM "courses" INNER JOIN "sections" ON "sections"."course_id" = "courses"."id" INNER JOIN "quizzes" ON "quizzes"."section_id" = "sections"."id" INNER JOIN "course_members" ON "courses"."id" = "course_members"."course_id" WHERE (NOT (("quizzes"."completed" = 'f' OR "quizzes"."completed" IS NULL))) AND "course_members"."member_id" = ?  [["member_id", 1]]
Другие вопросы по тегам