LondonGuy
LondonGuy

Reputation: 11098

What does self do in ruby on rails?

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

Answers (4)

acco
acco

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

David Nehme
David Nehme

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

rdvdijk
rdvdijk

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

Ben Kreeger
Ben Kreeger

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

Related Questions