ironsand
ironsand

Reputation: 15141

How to let `self` work in a class

I want to downcase a user's email address before saving it to database in rails. I am at this page using this code:

class User < ActiveRecord::Base
  before_save {self.email = email.downcase}
end

It also works if I write self.email = self.email.downcase, but it doesn't work if I write email = email.downcase. Under which condition can self be omitted?

Upvotes: 2

Views: 231

Answers (2)

user2864740
user2864740

Reputation: 61865

self must always be supplied when wishing to use a setter1 on the left-hand side of an assignment, e.g. self.x = val or self.x += val2.

self can be omitted for getters (which are just normal method calls) when there is not a local variable that shadows the method.

Expressions of the form x = val or x += val - that is to say, without self - always assign to the local variable x. In this case that means a value was being assigned to the local variable email (not to be confused with self.email), which was then discarded when the block exited.


1 See What is attr_accessor in Ruby? for how getters/setters are implemented.

2 When ruby sees self.x = y it treats it like self.__send__(:x=, y). That is, the setter (which is just a normal method with a trailing equals in the name) is called magically.

Upvotes: 7

OneChillDude
OneChillDude

Reputation: 8006

email = email.downcase

Makes a new variable that overwrites the class synthesis of email. My rule of thumb is to always prefix attributes with self. While Ruby allowys you to do either, this is part of the POLS or Principle Of Least Surprise. When you work with other developers it is better if they don't have to dig through your code, and just know that email is an attribute. Bottom line, don't omit self.

And for gods sake, space out your code a tad. Readability is key.

before_save { self.email.downcase! }

Upvotes: 1

Related Questions