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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With