Topic: Complex Relationships

I have three models: User, Friendship, and Photo. Each Friendship belongs_to a user and a friend (both Users). Each photo belongs_to a User. I want to implement a "recent photos" list that only shows photos uploaded by the user's friends. I've been staring at this problem for a while now but I can't figure it out. Is this possible?

Thank you very much!

Re: Complex Relationships

Could you post the User and Friendship models, or at least tell us what kind of relationship you have between the two? You say each Friendship belongs_to a user. Does it also have_many users? Is it a has_many :through type deal?

Re: Complex Relationships

Oops, sorry! Here you go:

class User < ActiveRecord::Base
  has_many :friendships
  has_many :friends, :through => :friendships
  has_many :photos, :order => "created_at desc"
end

class Photo < ActiveRecord::Base
  belongs_to :user
end

class Friendship < ActiveRecord::Base
  belongs_to :user
  belongs_to :friend, :class_name => 'User', :foreign_key => 'friend_id'
end

Re: Complex Relationships

Try this:

@user = User.find(:first) # fetch a user anyway you want
@photos = Photo.find_all_by_user_id(@user.friends)

Rails allows you to pass an array of models/ids to a condition like this and it will automatically find the photos which belong to the passed friends.

There's probably a slightly more optimized way to do this (to make it only one query instead of two) but try this for now.

Railscasts - Free Ruby on Rails Screencasts

Re: Complex Relationships

I tried Photo.find_all_by_user_id(@me.confirmed_friends), but it returns zero results. (confirmed_friends returns a Friendship)... It seems like it should work, though.

Re: Complex Relationships

SupaPuerco wrote:

I tried Photo.find_all_by_user_id(@me.confirmed_friends), but it returns zero results. (confirmed_friends returns a Friendship)... It seems like it should work, though.

It needs to return a User model, not a Friendship model. Does confirmed_friends return Users?

Railscasts - Free Ruby on Rails Screencasts

Re: Complex Relationships

Even if I return an array of Users it still seems to return zero results... weird.

Re: Complex Relationships

I recommend opening script/console and playing around with the model in there. In my tests this should work.

Photo.find_all_by_user_id(User.find(:all))

Of course you would replace User.find(:all) with anything that returns an array of users. Do some testing to see what's not working. Perhaps @me.confirmed_friends isn't returning what you expect?

Also, open up the development.log file to see what queries are being run on the database. You should see something like this:

SELECT * FROM photos WHERE user_id IN (1, 2, 3, ...)

Railscasts - Free Ruby on Rails Screencasts