Использование OR с запросами в области

В Rails3 у меня есть:

Class Teacher
  #  active                 :boolean
  has_and_belongs_to_many :subjects

Class Subject
  #  active                 :boolean
  has_and_belongs_to_many :teachers

Я пытаюсь построить область Учителя, которая возвращает все Teachers которые active или связаны с Subject то есть active,

Эти области работают индивидуально, но как объединить их как единую область с операционными системами?

scope :active_teachers, where(active: true)
scope :more_active_teachers, joins(:subjects).where(:subjects => {active: true})

Я попробовал это без успеха:

scope :active_teachers, where(active: true).or(joins(:subjects)
      .where(:subjects => {active: true}))

ОБНОВИТЬ:

Я думал, что у меня есть решение, но оно больше не лениво загружается, дважды попадает в базу данных и, что самое важное, возвращает массив, а не объект AR!

scope :active_teachers, where(active: true) |
                        joins(:subjects).where(:subjects => {active: true})

4 ответа

Решение

У тебя есть Squeel to your rescue. Подробнее здесь.

Using that, you could define something like:

class Teacher
  ...
  scope :active_teachers, joins{subjects}.where {(active == true) | (subjects.active == true)}
  ...
end

Я думаю, что краткий ответ: ты не можешь.

Ориентация в коде может прервать ленивую загрузку... на самом деле это никак не обойти, так как вам нужна база данных для оценки. ActiveRecord не может выполнять оценки в областях, не выполняя каждый подпункт отдельно.

Примерно так должно работать следующее:

joins(:subjects).where("subjects.active = true OR teachers.active = true")

Не так элегантно, но может быть включено в метод для повторного использования.

Вы можете решить эту проблему, перейдя на AREL. Смотрите этот вопрос так, как это сделать.

AREL ИЛИ Состояние

Или из исходного кода AREL README.md. Я думаю (но не проверил), что это приведет к следующему для вашего конкретного примера.

teachers.where(teachers[:active].eq(true).or(subjects[:active].eq(true)))

Удачи!

Для этого есть запрос на извлечение rails ( https://github.com/rails/rails/pull/9052), но тем временем кто-то создал патч обезьяны, который вы можете включить в свои инициализаторы, что позволит вам сделать это. это и до сих пор дает вам ActiveRecord::Relation:

https://gist.github.com/j-mcnally/250eaaceef234dd8971b

С этим вы сможете или ваши прицелы, как это

Teacher.active_teachers.or.more_active_teachers

или напишите новую область

scope :combined_scopes, active_teachers.or.more_active_teachers
Другие вопросы по тегам