When to use self in ActiveRecord models
A common mistake of Rails rookies coming from a .NET or JAVA background is overusing the self
keyword. Imagine the following simplified model from a battleship game
class Ship < ActiveRecord::Base
validates :start_x, :start_y, :end_x, :end_y
def randomize(length)
...
end
end
and we want to create a method that randomizes the ship coordinates. The first approach might look like this.
def randomize(length)
start_x = rand(10)
start_y = rand(10)
end_x = start_x + 5
end_y = start_y
end
It’s not a very good randomizing strategy, but it doesn’t work either. Your model attributes are still nil, but why?
With the previous code, you create a new local variables called start_x
, start_y
, end_x
and end_y
. They get assigned and after that silently discarded by the mighty garbage collector.
You might have noticed, that somewhere in the documentation you saw a keyword self
– the alternative to C# this
. That must solve the problem, let’s fix it.
def randomize(length)
self.start_x = rand(10)
self.start_y = rand(10)
self.end_x = self.start_x + 5
self.end_y = self.start_y
end
Cool, now it works…but with one small issue. You overused the self
keyword.
You should use it only in two cases and that’s if you want to differentiate your call from
- local variable creation or
- method call with the same name.
Let’s removed the unnecessary words and the final code should look like this.
def randomize(length)
self.start_x = rand(10)
self.start_y = rand(10)
self.end_x = start_x + 5
self.end_y = start_y
end
Don’t overuse self
keyword like many C# and JAVA developers tends to do.