Replacing finder_sql with named_scope

I thought I would share a bit on here how I was able to use named_scope
to save me from an issue I was facing. I have a join model between Group
and User, called GroupsUser. It is your standard join table containing
the two foreign keys, as well as some additional information pertaining
to that association such as if that user is an admin for that group, and
if their membership has been accepted if it is a private group.

I needed a way to also look up photos in the group, but photos are only
in the group because they belong to the user in the group. As you
probably are aware, you are not able to chain up has_many :through
associations, and I already required one on Group for has_many :users,
:through=>:groups_users, and vice-versa. This meant I had (what I
thought) only one option, to write SQL in the finder_sql option for my
:photos association on the Group model. I found out, however, very
quickly that this would not allow me to still chain on additional Photo
scopes as the finder_sql is static, and thus appends its “select …” to
any query it attempts to attach itself to, such as another named_scope.

My solution? Use the same SQL that I would need to already write for
finder_sql, but split it into options in a named_scope on the Photo
model, and then call that scope from the group instance. This allows me
to chain as many additional scopes or finders as I need without any SQL
breakage. See below.

class Group < ActiveRecord::Base
has_many :groups_users, :dependent=>:destroy
has_many :users, :through=>:groups_users

def photos

class User < ActiveRecord::Base
has_many :groups_users
has_many :groups, :through=>:groups_users

class GroupsUser < ActiveRecord::Base
belongs_to :user
belongs_to :group

class Photo < ActiveRecord::Base
belongs_to :user

named_scope :in_group, lambda{|group| {
:joins=>“INNER JOIN users on = photos.user_id INNER
JOIN groups_users ON = groups_users.user_id”,
:conditions=>["groups_users.group_id = ?",]