Sunday, May 10, 2009

Assignments, Increments, Decrements,... in ActiveRecord

Maybe you've already come across the fact that if you want to set an attribute of an ActiveRecord model within a method, the following code won't work:

  def enable!
    enabled = true
    save!
  end

The problem is that instead of calling the method enabled= a local variable enabled is initialized and set true. Since the scope of this variable is only the method itself, the state of the object isn't altered and therefore nothing changes when saving the model.

To avoid this behaviour, you have to call the method on the object itself explicitly:

  def enable!
    self.enabled = true
    save!
  end

So far so good. But what I found quite surprising is that the same applies to all operators containing an assertion. So instead of writing

  def double!
    price *= 2
    save!
  end

you have to use

  def double!
    self.price *= 2
    save!
  end

Admittedly — if you think about it a little it's not that surprising anymore, since the method is nothing but the short form of

  def double!
    price = price * 2
    save!
  end

which makes the problem obvious again: While the right price in the term refers to the getter method, the left one is just a local variable again.

The same applies for all operators making use of a ...= setter method, e.g. +=, -=, /=, etc.

No comments:

Post a Comment

 
DreamHost coupon code