Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 759
Andrew Avatar asked Mar 03 '11 16:03

Andrew


People also ask

Does Ruby use self?

self is a special variable that points to the object that "owns" the currently executing code. Ruby uses self everwhere: For instance variables: @myvar. For method and constant lookup.

What is ActiveRecord in Ruby on Rails?

Active Record is the M in MVC - the model - which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database.

Is ActiveRecord an ORM?

ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code. When you need to make changes to the database, you'll write Ruby code, and then run "migrations" which makes the actual changes to the database.

What does ActiveRecord base do?

ActiveRecord::Base indicates that the ActiveRecord class or module has a static inner class called Base that you're extending.


1 Answers

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.

like image 134
pinkmexican Avatar answered Sep 23 '22 11:09

pinkmexican