I have a Place model and an Event model. Places can have events that take place on a specific date.
How can I set up my associations and finders to load all places including (eager loading) their events at a specific date without N+1 query problem?
What I've tried:
class Place
has_many :events
end
Place.all.preload(:events).where("events.start_date > '#{time_in_the_future}'")
#ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: missing FROM-clause entry for table "events".
Place.all.includes(:events).where("events.start_date > '#{time_in_the_future}'").references(:event)
# only loads places that have an event at the specific date and not all places including their events (if there are any events).
I successfully came up with an association that does what I want but is not dynamic (does not accept parameters)
class Place
has_many :events, -> {where("events.start_date > '#{Time.now}'")}
end
Place.all.preload(:events)
# perfect: executes two queries: One to get all 'places' and one to get all 'events' that belong to the places and merges the 'events' into the 'place' objects.
# But I can't pass time as a parameter, so time is always Time.now (as specified in the has_many association).
# Place.all.preload(:events).where(xyz) gives wrong results like the examples above.
The problem for me is that I can't find a way to preload/eager load with dynamic conditions. Because preload and includes expect the association name as a parameter and can′t be refined with parameters. At least I found no way to do this.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…