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