Tuesday, April 18

has_many :continuing sagas

A few quick updates this morning.

First, I fixed a little boo boo in the implementation from my last post related to my deferral of the "find_by_widget_id" call. I was calling it on the wrong model, but returning the correct value oddly enough to fool my unit tests. Once I started using the tool in real code I discovered the error.

Secondly, Josh Susser has posted a write-up (a lot more eloquently) of exactly what I'm dealing with on his blog. He concludes his explanation with the claim, "I do actually have some ideas about how to add some more magic ... I'll have to save that for next time." Here's to hoping he doesn't wait too long to share.

Finally, I had to deploy a self-referential cross-reference model last night, one that links to itself. Essentially, a "friends" mapping that maps Collectors to Collectors. This, of course, broke my little hack as the "guessed" foreign key no longer worked. However, I think I might be able to dig it up since it is passed in to the "belongs_to" declaration of the mapping model. If I figure it out, I will of course post the new code.

So without further ado, here's the latest.

module ActiveRecord
module Associations
class AssociationCollection < AssociationProxy

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

def teds_find_relationship_wrapper( widget )
conditions = "#{ teds_guess_foreign_key( widget ) } = #{ widget.id }"
find( :first, :conditions => conditions )
end

def include?( widget )
unless widget.instance_of?( @reflection.klass )
widget = teds_find_relationship_wrapper( widget )
end
super( widget ) # ! index( widget ).nil?
end

alias_method :old_delete, :delete

def delete( widget )
unless widget.instance_of?( @reflection.klass )
widget = teds_find_relationship_wrapper( widget )
end
unless widget.nil? # I should probably raise an error
old_delete( widget )
end
end

alias_method :old_push, '<<'

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

end
end
end

No comments: