Software dev, tech, mind hacks and the occasional personal bit

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!

Previous

How to do Tax Deductions for an Investment Property in NSW, Australia

Next

Dance Dance Dance

4 Comments

  1. kedoin

    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!

  2. James Crisp

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

  3. Anonymous

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

  4. James Crisp

    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.

Powered by WordPress & Theme by Anders Norén