Reputation: 11098
I'm on railcasts just practicing some rails and have come across something I'm trying to understand.
I didn't get what the "self" on the authenticate method was doing. So I deleted it and tested the login of my app to see if it would show an error and it did:
error:
**NoMethodError in SessionsController#create
undefined method `authenticate' for #<Class:0x00000102cb9000**>
I would really appreciate if someone could explain exactly what that "Self" is doing. I was trying to figure out exactly what was going on but can't get my head around it.
Method is defined in model and called in sessions_controller.. I've been continuously deleting my app and starting from scratch to get the hang of it and many things make sense to me each time i start again but I'm stuck at "self".
I'm just the type of person who likes to understand why something works.
controller:
def create
user = User.authenticate(params[:email], params[:password])
if user
session[:user_id] = user.id
redirect_to root_path, :notice => "Logged In"
else
flash.now.alert = "Invalid credentials"
render "new"
end
end
model:
def self.authenticate(email, password)
user = find_by_email(email)
if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
user
else
nil
end
end
Upvotes: 6
Views: 9597
Reputation: 550
For the sake of completion and to thwart future headaches, I'd like to also point out that the two are equivalent:
class User
def self.authenticate
end
end
class User
def User.authenticate
end
end
Matter of preference.
Upvotes: 3
Reputation: 21572
class User
def self.xxx
end
end
is one way of defining class method while
class User
def xxx
end
end
will define an instance method.
If you remove the self. from the def, you will get a method not found error when you do
User.authenticate
because you are trying to call a method on a class rather than an instance of the class. To use an instance method, you need an instance of a class.
Upvotes: 3
Reputation: 4398
This is a basic ruby question. In this case, self
is used to define a class method.
class MyClass
def instance_method
puts "instance method"
end
def self.class_method
puts "class method"
end
end
Which are used like this:
instance = MyClass.new
instance.instance_method
Or:
MyClass.class_method
Hope that clears things up a little bit. Also refer to: http://railstips.org/blog/archives/2009/05/11/class-and-instance-methods-in-ruby/
Upvotes: 13
Reputation: 6344
self
defines a method of the class instead of the instance of the class. So with def self.authenticate
you can do the following:
u = User.authenticate('[email protected]','p@ss')
Instead of doing…
u = User.new
u.authenticate('[email protected]','p@ss')
That way, you don't have to create an instance of user to authenticate one.
Upvotes: 5