Получить подмножество отношений «многие ко многим» в Rails/ActiveModel

Например, у меня есть врачи, у которых много назначений пациентам. Я хочу получить всех пациентов, которые в настоящее время активны в назначении:

class Doctor < ActiveRecord::Base
  attr_accessible :name
  has_many :appointments
  has_many :patients, through: :appointments
end

И модель назначения:

class Appointment < ActiveRecord::Base
  attr_accessible :patient_id, :began_at, :finished_at, :doctor_id
  belongs_to :patient
  belongs_to :doctor
  scope :active, where(finished_at: nil)
end

Теперь я могу сделать что-то вроде doctor.appointments.active, чтобы получить активные текущие встречи. Но я хочу, чтобы пациенты легко получали эти назначения. Есть ли способ сделать что-то вроде doctor.appointments.active.patients? Или doctor.patients.active имело бы больше смысла.

Могу ли я добавить область active в строку has_many :patients в классе Doctor?




Ответы (1)


Вы должны быть в состоянии сделать

has_many :patients, :through => :appointments do
  def active
    where("appointments.finished_at is NULL")
  end
end

потом:

doctor.patients.active
person Joshua Scott    schedule 20.05.2013
comment
странно не работает. SQL, который он выводит, имеет смысл, но я получаю пустой набор, даже несмотря на то, чтоassigns.finished_at на самом деле nil - person at.; 21.05.2013
comment
поле finished_at — это nil в Ruby. Однако, когда я перехожу к sqlite3, поле пусто. Я не знаю, что это такое. Если я сделаю sqlite> select * from appointments where finished_at=null;, я ничего не получу взамен. Даже если я сделаю where finished_at='', я тоже ничего не получу взамен. - person at.; 21.05.2013
comment
Если я наберу следующее в rails console, я верну встречу, странно, как nil работает в Rails, но не в sqlite3: Appointment.where(finished_at: nil) - person at.; 21.05.2013
comment
Хорошо, я разобрался, видимо в SQL нельзя проверить на NULL с помощью =. Вы должны сделать следующее: appointments.finished_at is ? - person at.; 21.05.2013
comment
Я обновил оператор where, чтобы он был чистым SQL, так как это все, что нам нужно. Извини за это. - person Joshua Scott; 22.05.2013