I have three models
User
has_many :reviews
has_many :review_invites
end
Review
has_one :user
end
ReviewInvite
has_one_user
end
For someone to access a particular review, they need to own it, or be
invited.
@user = User.find(user_id
:include => [:review, :review_invite],
:condition => 'filter to a certain review
id);
Even if a user has no review invites or owns no reviews, I still want
the user data returned, with all other fields padded null, ie standard
outer join behavior.
Rails generates SQL like the following:
select columns
from users
left outer join reviews on reviews.user_id = users.id
left outer join reviewers on reviewers.user_id = users.id
where my_conditions_clause
and user.id = user_id;
In my mind, this SQL is not correct for what I want (it doesn’t work
correctly either). It seems to join all the tables and then apply a
filter to joined result, while I really want to filter the tables in
the join conditions, like this:
select columns
from users
left outer join reviews on reviews.user_id = users.id AND REVIEWS.ID
= param[:review_id]
left outer join reviewers on reviewers.user_id = users.id AND
REVIEWERS.ID = param[:review_id]
where user.id = user_id;
Which does give me the answer I want, even if a user has no reviews or
invites.
I have fudged this behavior in before when using a single :include by
specifying a joins parameter, but I cannot see how I can do this with
two associations. Is there any way to get what I want without
resorting to SQL?
It seems to me like the Rails way to do this is something like
@user = User.find(user_id
:include => [:review => { :conditions =>
[ ‘review.id = ?’, review_id ] },
:review_invite =>
{ conditions => [‘reviewers.review_id’ = ?] } )
But I cannot find anything in the docs that implies this is possible.
Please help!
Thanks,
Stephen.