Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Eager loading with has_many through

I have a User model.

A user has many integrations.

An integration is join to a profile via integration_profiles which contains a column data.

I want to eager load all of a user's profiles.

class Integration < ActiveRecord::Base
 has_many :integration_profiles
 has_many :profiles, through: :integration_profiles
end

class IntegrationProfile < ActiveRecord::Base
 belongs_to :integration
 belongs_to :profile
end

class Profile < ActiveRecord::Base
 has_many :integration_profiles
 has_many :integrations, through: :integration_profiles
end

I tried this:

all = User.first.integrations.includes(:profiles)

But I when I did all.count

=> 2

But when I do

all = User.first.integrations.joins(:profiles)
all.count
=> the correct total

Should I be using includes or joins? I have always used includes so not sure why this isn't working here

like image 398
Mohamed El Mahallawy Avatar asked May 04 '14 18:05

Mohamed El Mahallawy


1 Answers

When you do

all = User.first.integrations.joins(:profiles)
all.count

the integrations records would be counted for the first User and with an inner join query on profiles.

And when you do

all = User.first.integrations.includes(:profiles)
all.count

again you get integrations count BUT without join query with profiles as profiles are eager loaded with separate queries because of includes

It seems that you simply want the profiles count associated to a given user. The best way to achieve this would be, to create an association between User and Profile model

User ==> has_many :profiles, through: :integration

Once you do that, you can directly access User.first.profiles.count to get the count of all associated profiles of a particular user.

The other option would be (if you don't want to go with above option) to loop through all integrations and sum up all profiles.count for every integration.

Choose the option that best suits your needs.

like image 150
Kirti Thorat Avatar answered Sep 28 '22 13:09

Kirti Thorat