Take the 2-minute tour ×

I have a has_many though association like this:

has_many :memberships, :dependent => :destroy

has_many :groups, :through => :memberships

has_many :users, :through => :memberships
has_many :microposts

belongs_to :user
belongs_to :group

First I need to know the query to get all the groups of a user, after that I need a way to show all the microposts of those groups. Is it possible to get one query with that information?

Thanks a lot!

share|improve this question
add comment

1 Answer

up vote 2 down vote accepted

To get a user's groups:

some_user = User.find(some_id)

To get the microposts, you could do:

some_user.groups.each do |group|
  puts group
  puts group.microposts

However, this would cause a separate query to be generated to collect the microposts of each group. This can be fixed by eager-loading the microposts using includes:

some_user.groups.includes(:microposts).each do |group|
  puts group
  puts group.microposts

Now only 2 queries will be generated - one to fetch the groups, and one to fetch all microposts associated with these groups. Behind the scenes, ActiveRecord will match the microposts to the correct group, and return them accordingly when calling .microposts on a group.

To get all microposts as a hash, you can use each_with_object to collect them:

@group_microposts = some_user.groups.includes(:microposts).
                              each_with_object({}){|group, h| h[group] = group.microposts}

This will return a hash in the form { group => microposts }.

To get them as an array, you could just do:

@microposts = some_user.groups.includes(:microposts).map(&:microposts).flatten

However, there is an even more efficient way to do this if you don't need the group information at all:

@microposts = Micropost.joins(:group => :users).where(:users => {id: some_user.id})

This second method is faster because of 2 reasons - it requires only a single query (no eager loading needed) and the db lookup is more efficient since it can use available indices to perform the necessary joins rather than filter against a literal integer list (which can get slow as the list gets larger).

share|improve this answer
Thanks! how can I save all the microposts of all the groups that belongs to a user in a instance variable? So in my view I can use @microposts or something like that... –  Julio Ahuactzin May 21 '13 at 3:38
Do you need them grouped by group or just as a big array of microposts? –  PinnyM May 21 '13 at 3:38
A big array.. . –  Julio Ahuactzin May 21 '13 at 3:46
Updated for both options ;) –  PinnyM May 21 '13 at 3:48
Super! thanks a lot ;) –  Julio Ahuactzin May 21 '13 at 3:54
show 6 more comments

Your Answer


