Reputation: 17812
I have the following models:
Relations are simple:
class Staff < ApplicationRecord
has_many :seminars
end
class Seminar < ApplicationRecord
belongs_to :staff
has_many :schedules
has_many :future_schedules, -> { future }, class_name: 'Schedule'
has_many :past_schedules, -> { past }, class_name: 'Schedule'
end
class Schedule < ApplicationRecord
belongs_to :seminar
scope :future, -> { where('starts_at > ?', Time.now) }
scope :past, -> { where('ends_at > ?', Time.now) }
end
I can easily do: seminar.future_schedules
& seminar.past_schedules
, but here is the issue: I would like to have a way to get those seminars for a staff that have schedules in future.
What I have tried:
has_many :future_seminars, -> { future_schedules }, class_name: 'Seminar'
But the problem is: I can't pass future_schedules
in above line, because it isn't a scope.
has_many :future_seminars, -> { where('schedules.starts_at > ?', Time.now) }, class_name: 'Seminar'
But it says: schedules.starts_at
is not a column, and it is so. So is there anyway I can load schedules
for seminars in advance using something like includes
?
Upvotes: 2
Views: 345
Reputation: 138
You can perhaps do something like this:
In Seminar model:
scope :future_seminars, -> { joins(:schedules).where("schedules.starts_at >", Time.current) }
In Staff model:
has_many :future_seminars, -> { future_seminars }, class_name: 'Seminar'
Also, I think there's a type in the scope for past schedules. It should be like this
scope :past, -> { where('ends_at < ?', Time.now) }
Upvotes: 2
Reputation: 52376
If you need a highly performant method then you may need to blend in some SQL.
Something like:
Staff.find(32).seminars.
where(Schedule.where("schedules.seminar_id = seminars.id").
where("schedules.starts_at > ?", Time.now).exists)
Upvotes: 1