Reputation: 1415
I'm trying to perform the following query in Rails 5 in a way that it doesn't trigger N+1 queries when I access each events.contact:
events = @company.recipients_events
.where(contacts: { user_id: user_id })
I tried some combinations of .includes, .references and .eager_loading, but none of them worked. Some of them returned an SQL error, and other ones returned a nil object when I access events.contact.
Here's a brief version of my associations:
class Company
has_many :recipients
has_many :recipients_events, through: :recipients, source: :events
end
class Recipient
belongs_to :contact
has_many :events, as: :eventable
end
class Event
belongs_to :eventable, polymorphic: true
end
class Contact
has_many :recipients
end
What would be the correct way to achieve what I need?
Upvotes: 3
Views: 3963
Reputation: 569
If you already know user_id when you load @company, I'd do something like this:
@company = Company.where(whatever)
.includes(recipients: [:recipients_events, :contact])
.where(contacts: { user_id: user_id })
.take
events = @company.recipients_events
OR, if not:
events = Company.where(whatever)
.includes(recipients: [:recipients_events, :contact])
.where(contacts: { user_id: user_id })
.take
.recipients_events
The ActiveRecord query planner will determine what it thinks is the best way to get that data. It might be 1 query per table without the where
, but when you chain includes().where()
you will probably get 2 queries both with left outer joins on them.
Upvotes: 3