I’m trying to understand when to use self.method_name vs. when to use Classname.method_name.
In the example below, why does “before_create” need to reference “User.hash_password” instead of “self.hash_password” or just “hash_password”?
Since we are in the User class already, I thought the before_create method would “know” that “hash_password” is a member of its own class and would not need any special syntax to refer to it.
require 'digest/sha1'
class User < ActiveRecord::Base
attr_accessor :password
attr_accessible :name, :password
validates_presence_of :name, :password
validates_uniqueness_of :name
def before_create
self.hashed_password = User.hash_password(self.password)
end
def after_create
@password = nil
end
def self.login(name, password)
hashed_password = hash_password(password || "")
self.find(:first, :conditions => ["name = ? and hashed_password = ?", name, hashed_password])
end
def try_to_login
User.login(self.name, self.password)
end
private
def self.hash_password(password)
Digest::SHA1.hexdigest(password)
end
end
In this example,
User.hash_passwordcalls thehash_passwordmethod on the classUser, whereasself.hashed_password=calls thehashed_password=method on this particular instance ofUser.If you replace
User.hash_passwordwithself.hash_password, Ruby would complain with aNoMethodError, because no instance method by the name ofhash_passwordexists in the classUser. You could replace it withself.class.hash_password, though.If you replace
self.hashed_password=with simplyhashed_password=, Ruby would create a local variable namedhashed_password, rather than call the instance methodhashed_password=. You need to explicitly addselfif you want to call attribute writers.The
selfin the method definition (def self.hash_password) makeshash_passworda class method instead of an instance method. In this context,selfrefers to the class. In the context of an instance method,selfrefers to an instance.