Andy McKay

Mar 10, 2008

Another reason to hate Rails


Supposing I have a model sample, and column foo for the model samples in the DB. In the following example, what does Sample.find(:first).wtf print out?

require 'sampletwo'

class Sample < ActiveRecord::Base
    def wtf
        foo
    end
    
    def foo
        "here 1"
    end
end

def foo    
    "here 2"
end

Too easy, the answer is "here 1". Ok how about something a bit harder. What does Sample.find(:first).wtf print out now?

class Sample < ActiveRecord::Base
    def wtf
        foo
    end
end

Is it the column on the database? No. It's the method foo in the library sampletwo.rb, which you won't know. But is now imported in environment.rb. The order for lookup (if I've got this right is):

  • Does the method exist on the object (and presumably in the inheritance tree, but not sure)
  • Does the method exist somewhere else in the namespace, eg in the module
  • Does anything else import that value into the namespace, eg any require you might have in your environment or your current model
  • Lookup the database column

I've never like the fact that Ruby's require imports everything into that namespace the module wants to import, you don't have any choice. It's rather like this in Python:

from wx import *

The end result is that when you collaborate on things or end with big honking 2,000 line models you get a huge amount of conflict and sitting there trying to figure out where something comes from. You normally keep your database manager open in another window so you can query it and see what's there.

Meanwhile in Django land, there's an explicit model, explicit import statements (* imports are possible but discouraged in Python) and explicit use of self.