Reputation: 370
This is not so much a how-to question but is more of a why question. Consider the example below, where I am trying to set a default email in before save.
class Organization < ActiveRecord::Base
before_save :set_default_email
def set_default_email
email ||= 'info@'+ domain
end
end
The above method unfortunately does not work. Instead if add a self like shown below, it works fine and the value gets passed on to the db.
def set_default_email
self.email ||= 'info@'+domain
end
However, given that the default receiver in ruby is self (which is why it understands domain etc.), shouldn't self.email and email be the same thing?
Upvotes: 2
Views: 1307
Reputation: 32933
Just to expand on the other answers a bit, if you break down ||=
you get
email = email || 'info@'+ domain
which is equivalent to
email = self.email || 'info@'+ domain
self.email
is nil, so it will evaluate to
email = 'info@'+ domain
And that's set a local variable, but doesn't call the email=
method.
This is one reason why it's good practice to ALWAYS use self.
rather than rely on Ruby's default scoping. It's also much more readable: another coder scanning your code can easily see that when you do self.email =
(or self.email ||=
in your case) you're calling the setter method, rather than defining a local variable.
Upvotes: 2
Reputation: 3347
if you don't use self.
what you are doing is defining a local variable, instead of calling the setter
Upvotes: 1
Reputation: 51151
No, Ruby assumes construction variable = value
to be local variable assignment. That's why in setter method, you have to point receiver explicitly.
Upvotes: 2