Why isn't self always needed in ruby / rails / activerecord?

Andrew picture Andrew · Mar 3, 2011 · Viewed 8.8k times · Source

In testing a getter/setter pair in a rails model, I've found a good example of behavior I've always thought was odd and inconsistent.

In this example I'm dealing with class Folder < ActiveRecord::Base.

Folder belongs_to :parent, :class_name => 'Folder'

On the getter method, if I use:

def parent_name
  parent.name
end

...or...

def parent_name
  self.parent.name
end

...the result is exactly the same, I get the name of the parent folder. However, in the getter method if I use...

def parent_name=(name)
  parent = self.class.find_by_name(name)
end

... parent becomes nil, but if I use...

def parent_name=(name)
  self.parent = self.class.find_by_name(name)
end

...then then it works.

So, my question is, why do you need to declare self.method sometimes and why can you just use a local variable?

It seems the need for / use of self in ActiveRecord is inconsistent, and I'd like to understand this better so I don't feel like I'm always guessing whether I need to declare self or not. When should you / should you not use self in ActiveRecord models?

Answer

pinkmexican picture pinkmexican · Mar 3, 2011

This is because attributes/associations are actually methods(getters/setters) and not local variables. When you state "parent = value" Ruby assumes you want to assign the value to the local variable parent.

Somewhere up the stack there's a setter method "def parent=" and to call that you must use "self.parent = " to tell ruby that you actually want to call a setter and not just set a local variable.

When it comes to getters Ruby looks to see if there's a local variable first and if can't find it then it tries to find a method with the same name which is why your getter method works without "self".

In other words it's not the fault of Rails, but it's how Ruby works inherently.

Hope that helps.