Saturday, April 15

has_many :polishing

As I noted in the update to my last post, I had a little bug in my extension of the has_many feature that broke the old vanilla usage. The bug was in the way that "super" called from the "<<" override wasn't correctly/consistently deferring to the former implementation. I couldn't figure out why it didn't work, but I did figure out how to work around it. I just aliased the method name and deferred to the alias. Slick.

Oh, I also moved the extension into it's own file "lib/has_many_extensions.rb":

module ActiveRecord
module Associations
class AssociationCollection

def foreign_key( widget )
widget.class.to_s.downcase + '_id'
end

def find_relationship_wrapper( widget )
instance_eval "#{ @reflection.klass }.find_by_#{ foreign_key( widget ) }( #{ widget.id } )"
end

def include?( widget )
unless widget.instance_of?( @reflection.klass )
widget = find_relationship_wrapper( widget )
end
super( widget )
end

alias_method :old_delete, :delete

def delete( widget )
unless widget.instance_of?( @reflection.klass )
widget = find_relationship_wrapper( widget )
end
old_delete( widget )
end

alias_method :old_push, '<<'

def <<( widget )
if widget.instance_of?( @reflection.klass )
old_push( widget )
else
create( { foreign_key( widget ) => widget.id } )
end
end

end
end
end

Then I added the necessary "require" to the end of my "config/environment.rb" file:

require 'has_many_extensions'

Enjoy!

No comments: