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

  1. local variable creation or
  2. 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.


Would you like to get the most interesting content about programming every Monday?
Sign up to Programming Digest and stay up to date!