Initializing attributes on join models: best practice?

I have a join model represented by has_many :through with some conditions. Thanks to Jeremy Kemper’s patches (http://dev.rubyonrails.org/changeset/4786), I can add records to the collection. However, since I have a condition on the finders referencing an attribute, I would also like to set that attribute when I add records to the collection. Since Jeremy’s extensions don’t support before_add and after_add, the only solution I found was to add an extension and override the association methods.

Some code:

Here is the first association:

has_many :partner_children,

:class_name => ‘ClientsPartner’,

:foreign_key => ‘partner_id’

Here is what I would like to do:

Role.find(:all).each do |role|

has_many :“children_as_#{role.short_name}”,

:through => :partner_children, :source => :client,

:conditions => ["role_id = ?", role.id],

:before_add => lambda { (set attributes on join model) }

end

And here is what I ended up with:

Role.find(:all).each do |role|

children_as_role_extension = Module.new

children_as_role_extension.module_eval(<<-EOT)

def <<(*records)

  records.each do |record|

    @owner.partner_children.create(:client => record, :role_id => #{role.id})

  end

  reload

end

def delete(record)

  @owner.partner_children.find(:all, :conditions => 

      ["client_id = ? and role_id = ?", record.id, #{role.id}]

  ).each(&:destroy)

  reload

end

def clear

  @owner.partner_children.find(:all, :conditions => 

      ["role_id = ?", #{role.id}]

  ).each(&:destroy)

  reload

end

EOT

has_many :“children_as_#{role.short_name}”,

:through => :partner_children, :source => :client,

:conditions => ["role_id = ?", role.id], :extend => children_as_role_extension

end