0

I am trying to get all of a user's friends' posts and user info in one query.

I have tried to use includes(:users) but that doesn't seem to work and throws an error. I figured a manual join would be the best solution:

@friends = @user.friends
      .joins('inner join users on users.id = friends.user_id left outer join posts on users.id = posts.user_id')
      .select('posts.*, users.*, friends.*')

How do you access attributes from users and posts? doing a @friends.inspect only shows attributes from the friends table, and I can't do @friends.posts or @friends.users.

My model for friends and users looks like this:

class Friend < ActiveRecord::Base
  belongs_to :users
end

class User < ActiveRecord::Base
    has_many :friends
    has_many :users, through: :friends
end
user3822741
  • 55
  • 1
  • 8
  • A single user's friends would be a list of friends, and you want all their posts, that would be `friends.map(&:posts).flatten`. Given your `joins` clause, I believe using the code I just typed will work fine; check the log for the actual queries executed. If you want an explanation of how I used `map` there, let me know. – Satya Feb 26 '15 at 05:07
  • for some reason that's giving me an error.. undefined method `posts' for # – user3822741 Feb 26 '15 at 10:12
  • Oh, I see. According to the SQL in the `join` clause, your `posts` are related to `users`, not to `friends`. Something like `friends.map{|f| f.user.posts}.flatten` might work, if `Friend` had `belongs_to :user` (singular "user") which would be conventional Rails.... and that is also reflected in your SQL, so I suggest you make that change to `Friend` anyway :) – Satya Feb 26 '15 at 15:18
  • Off-topic: Not sure why `friends` is a separate table. Did you actually want to self-join on `users`, and since the relation is many-many, need a join table? This is vaguely related, I think: http://stackoverflow.com/questions/3396831/rails-many-to-many-self-join – Satya Feb 26 '15 at 15:21
  • Awesome, that's exactly what I was looking for. That's probably a better direction to head in - Thank you! – user3822741 Feb 26 '15 at 17:23

1 Answers1

0

According to the SQL in the join clause, your posts are related to users, not to friends. Something like this will work:

friends.map{|f| f.user.posts}.flatten 

if Friend had belongs_to :user (singular "user") which would be conventional Rails, and is reflected in the SQL you used, so has the overriding factor of being correct.

Satya
  • 4,458
  • 21
  • 29