Rails and the initialize() method

I spent a bit of time this weekend on a pet rails project. I came across a strange error when trying to create new records through the application. Editing was working just fine, but creating a new record just seemed to hang.

Breakpoints came to my rescue. In Ruby, they're really handy. You can put a 'breakpoint' call anywhere in your code, and if you have a breakpointer process running (start this with the command 'ruby script/breakpointer'), you jump straight into an interactive ruby console debug session when the breakpoint is hit.

Using the development log and a few breakpoints, I found the that the error was:

ArgumentError: wrong number of arguments (1 for 0)

And that it was caused by a line similar to this:

@order = order.new(params[:order])

Ie, the controller was creating a new order from the post parameters.

Then all became clear - some time earlier, I'd overridden the initialize() method in the order to default some dates. My code was similar to this:

def initializesuper()
  if (@new_record)
    self.validFrom = Date.today
    self.validTo = 1.year.from_now.to_date
  end
end

Great for creating new objects in my tests and console sessions where I always just created the object and then set properties. However, the controller was relying on passing in the post parameters in the constructor.

The solution is to accept any number of params and pass these to the base class:

def initialize(*params)super(*params)
  if (@new_record)
    self.validFrom = Date.today
    self.validTo = 1.year.from_now.to_date
  end
end

That way, the order can accept the post parameters in its constructor.

I'm very pleased to say that I can now create new records again!


Actions

Information

4 responses to “Rails and the initialize() method”

20 12 2006
kedoin (15:20:00) :

Thank you! I was just banging my head on a similar problem and couldn't figure out from the error message what was wrong!

I redid the initialize method as you suggested and everything's working!

23 12 2006
James Crisp (07:27:00) :

Thanks very much for your comment. I'm really glad to have helped.

26 12 2006
Anonymous (20:49:00) :

I think you should be using ActiveRecord's after_initialize callback for what you want to do.

27 12 2006
James Crisp (21:21:00) :

Agreed, sounds like after_initialize would work fine:

http://one.textdrive.com/pipermail/rails/2004-December/000681.html

and avoid requiring the more complex constructor.