0

I have two models Activities and Users

class Activity < ActiveRecord::Base
  has_and_belongs_to_many :users
end

class User < ActiveRecord::Base
  has_and_belongs_to_many :activities
end

I can load all the activities which are associated with users by calling

User.all.includes(:activities)

But this actually pulls up all my activity objects from the database, which can cause performance problems as the table is quite large. My requirement is only to get the activity_ids associated

I can directly get that by executing the plain sql on the join table

select activity_id from activities_users where user_id in (...)

My question is: Can I do get the above functionality in a rails friendly way

DanMatlin
  • 1,212
  • 7
  • 19
  • 37

1 Answers1

2

From has_and_belongs_to_many you could do things like @User.find(1).activity_ids

In terms of including them for a collection to avoid an n+1 query I don't think you can do it any way other than the way you've currently got it.

If you make it a has_many_through it'll have a model:

class Activity < ActiveRecord::Base
  has_many :user_activities
  has_many :users, through: :user_activities
end

class User < ActiveRecord::Base
  has_many :user_activities
  has_many :activities, through: :user_activities
end

class UserActivity < ActiveRecord::Base
  belongs_to :user
  belongs_to :activity
end

Then you can do @users = User.includes(:user_activities).all so when you loop over them and do something like it should avoid the n+1 query because you've already loaded them in.

@users.each do |user|
  user.activity_ids
end
j-dexx
  • 10,286
  • 3
  • 23
  • 36