www.flickr.com
Michael Kovacs' photos More of Michael Kovacs' photos
Recommend Me Cable Car Software logo

Sunday, January 29, 2006

Rails Realities part 7 (method name dictatorship)

Welcome to installment number 7 of the ruby realities series. Today was a day for nostalgia and made me remember how nice it is to have published and accurate API docs.
Allow me to elaborate. First some code...


class Loan < ActiveRecord::Base
belongs_to :mailing_address,
:class_name => "Address",
:foreign_key => 'mailing_address_id'
validates_presence_of :mailing_address

end

class Address < ActiveRecord::Base

def empty?
(self.line1.nil? || self.line1.empty?) &&
(self.line2.nil? || self.line2.empty?) &&
(self.city.nil? || self.city.empty?) &&
(self.state.nil? || self.state.empty?) &&
self.zip.nil?
end
end


What we have here are two active record classes. There's more to them than what's shown here but this is what was needed to reproduce my problem "in the small" as Sam likes to say. Now some more code that demonstrates the problem...


loan = Loan.new
loan.build_mailing_address
loan.valid?
pp loan.errors.inspect


running that code provided me an output of:
@errors={"mailing_address"=>["can't be blank"]}


Huh? but I just created an instance of mailing address. As an experiment I took out the
validates_presence_of :mailing_address

and things were fine. I was able to create my mailing address and have it saved to the database (updating properties on the same related object is another story itself.. one for a later date).

Digging further it turns out that the presence of empty? in Address is causing my validation problem. Renaming it to is_emtpy?, putting my
validates_presence_of :mailing_address
back into the relation fixes the original code above. Obviously I'm using a method name that is already in use but isn't documented anywhere in the rails API. It's not part of ActiveRecord::Base or Object. Nowhere in the :belongs_to API doc does it talk about this method being overridden or used by a proxy, unless I'm missing the warning somewhere. This could very well be user error or a bug and I'm sure to find out soon as I've filed a bug with the RoR team. http://dev.rubyonrails.org/ticket/3646

Sometimes standards and good docs really are your best friends.

Comments:
yeah that happened to me as well, but it was more my fault. i created a controller mix-in that dynamically created methods for moi. some time later, i wrote a method called "check" somewhere. the code wouldn't run, and i kept fiddling with script/console to find out why. breakpointed to learn that i had passed a parameter called "check" to the dynamic method mix-in which, ha ha, created a method of the same name "check", overriding the original definition. looks easy and obvious now, but, believe me, at that time it was really, really puzzling. i had to rename the first method to something else other than "check".

nowadays, i find magic methods absolutely hilarious. i guess it's the price i pay for the ability to shoot myself in the foot. i think it's better than stuff like _SO_set_lastName in turbogears.
 

Post a Comment





<< Home

This page is powered by Blogger. Isn't yours?