Хорошо, тогда. Итак, вот ваш код:
scope :unenrolled, where(Student.courses.count => 0)
Первая проблема здесь - это то, что вызывает ошибку: вы вызываете экземпляр метод courses
для класса Student
. Как следует из названия, вы можете вызывать метод экземпляра только для экземпляра класса, но не для самого класса. Например:
jim = Student.find(123)
jims_courses = jim.courses
Но вот что важно: когда вы вызываете scope
, вы находитесь в контексте class , то есть код не находится внутри метода экземпляра, поэтому он вызывается при первом объявлении вашей модели. В то время экземпляра нет, поэтому вы не можете просто вызвать courses
, как если бы вы были внутри одного из методов экземпляра Student
.
Но это спорный вопрос, поскольку вы немного неправильно поняли, как работает where
. Аргумент (ы), который вы указываете where
, должен быть условиями , которые соответствуют тому, что вы бы поставили после WHERE
в запросе SQL. Например, where(:eye_color => 'brown')
будет преобразован в предложение SQL WHERE
, например WHERE eye_color = 'brown'
. :eye_color => 'brown'
- это просто хэш с ключом :eye_color
, значение которого 'brown'
. Вызов функции в левой части =>
не имеет смысла, если функция не возвращает имя столбца / атрибута в вашей модели, которое ActiveRecord поймет.
Итак, теперь давайте выясним, что вы должны сделать. Если бы вы писали SQL-запрос, он бы выглядел примерно так:
SELECT `students`.*, COUNT(`courses_students`.*) AS `courses_count`
FROM `students`
JOIN `courses_students` ON `students`.`id` = `courses_students`.`student_id`
WHERE `courses_count` = '0'
GROUP BY `courses_students`.`student_id`;
Это примерно соответствует запросу ActiveRecord, например так:
Student.joins (: курсы). // AR автоматически присоединяется courses
хотя courses_students
выберите («студенты. , COUNT (курсы. ) AS courses_count»).
где ('courses_count = 0').
группа ( 'ID')
И вы можете вставить это прямо в вашу сферу:
scope :unenrolled, joins(:courses).
select('students.*, COUNT(courses.*) AS courses_count').
where('courses_count = 0').
group('courses.course_id')
Примечание: Эти запросы немного запутаны и могут потребовать небольшой доработки. Самый простой способ создать сложные запросы ActiveRecord - вводить их непосредственно в консоль Rails до тех пор, пока вы не получите желаемые результаты.
Надеюсь, это полезно!