Try it in a named_scope, thus:

class Person < AR::Base
  named_scope :as, lambda { |role_name| { :joins => 'CROSS JOIN
role_types', :conditions => ["(roles.role_type_id = role_types.id) AND
role_types.name = ?", role_name] } }
end

But I'm *almost* positive that that still won't be able to trigger the
named_scope :create_scope magic. The other thought would be to return
a custom subclass of AssociationCollection from your 'as' association
extension. You'd probably need to override a few methods (<<
especially) to take into account the source of the request (the
argument passed to as).

--Matt Jones


On May 12, 12:16 pm, Michael Schuerig <mich...@schuerig.de> wrote:
> On Tuesday 12 May 2009, Matt Jones wrote:
>
> > Haven't tried it, but have you considered switching the association
> > extension to a regular named_scope on Person? For simpler cases, I
> > know that the named_scope code is smart enough to use the scope
> > conditions to instantiate objects. Not sure if it will work here...
>
> If I understand you correctly, I've already considered that case.
>
> class Person < ActiveRecord::Base
>   named_scope :actors, ... # add a condition picking out the actors
> end
>
> Then, with
>
> movie.participants.actors
>
> I'd get the people who are participating in movie and who are actors.
> However, what I want are the people participating in movie *as* actors.
>
> It might be possible to get this to work as intended, but I tend to
> think it's not. Dealing with the joins involved is already tricky.
> ActiveRecord (almost) doesn't have an abstract model of queries, it more
> or less concatenates strings. There's no support for expressing, on the
> one hand, that a specific join is needed (without duplicating it), and
> on the other, that you want another, independent join.
>
> Michael
>
>
>
> > On May 11, 7:34 pm, Michael Schuerig <mich...@schuerig.de> wrote:
> > > I have a model layer containing Movie, Person, Role, and RoleType,
> > > making it possible to express facts such as "Clint Easterbunny is
> > > director of the movie Gran Milano".
>
> > > The relevant model and associations look like this
>
> > > class Movie < ActiveRecord::Base
> > >   has_many :roles, :include => :role_type, :dependent => :destroy
>
> > >   has_many :participants, :through => :roles, :source => :person do
> > >     def as(role_name)
> > >       self.scoped(
> > >         :joins => 'CROSS JOIN role_types',
> > >         :conditions => [
> > >           "(roles.role_type_id = role_types.id) +
> > >           " AND role_types.name = ?",
> > >           role_name
> > >         ]
> > >       )
> > >     end
> > >   end
> > >   ...
> > > end
>
> > > Querying is easy:
>
> > > m = Movie.find_by_title('Gran Milano')
> > > m.participants.as('director')
>
> > > However, changing relations is painful. It's already bad with
> > > has_many
>
> > > :through associations when the intermediate model is not completely
>
> > > dumb, and my scope trickery doesn't make it any better.
>
> > > Now, let's assume for a moment that participants was a plain
> > > has_many association. Then it would be possible to write things
> > > like
>
> > > m.participants.clear
> > > m.participants << Person.find_by_name('Steve McKing')
> > > m.participant_ids = params[:movie][:participants]
>
> > > With the given has_many :through, none of these work, as Role
> > > object won't validate without a role type. Anyway, what I would
> > > like to write is
>
> > > m.participants.as('actor').clear
> > > m.participants.as('actor') << Person.find_by_name('Steve McKing')
> > > m.participants.as('actor') =
> > > Person.find(params[:movie][:participants])
>
> > > I'm not sure this is possible with ActiveRecord as it is, but I'm
> > > looking forward to suggestions.
>
> > > Michael
>
> --
> Michael Schuerig
> mailto:mich...@schuerig.dehttp://www.schuerig.de/michael/
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to rubyonrails-talk@googlegroups.com
To unsubscribe from this group, send email to 
rubyonrails-talk+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to