5

Sono su una ferrovia che si esercita su alcuni binari e mi sono imbattuto in qualcosa che sto cercando di capire.Cosa fa il sé in ruby ​​su rotaie?

Non ho capito cosa stava facendo il "sé" sul metodo di autenticazione. Così ho cancellato e testato il login del mio app per vedere se avrebbe mostrato un errore e lo ha fatto:

error: 

**NoMethodError in SessionsController#create 
undefined method `authenticate' for #<Class:0x00000102cb9000**> 

Vorrei davvero apprezzare se qualcuno potesse spiegare esattamente che cosa quel "Sé" sta facendo. Stavo cercando di capire esattamente cosa stava succedendo, ma non riesco a capirlo.

Il metodo è definito nel modello e chiamato in session_controller .. Ho continuato a cancellare la mia app e iniziare da zero per ottenere il blocco di esso e molte cose hanno senso per me ogni volta che ricomincio ma sono bloccato a "sé".

Sono solo il tipo di persona a cui piace capire perché qualcosa funziona.

regolatore:

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 

modello:

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 

risposta

13

Questa è una domanda di rubino di base. In questo caso, self viene utilizzato per definire un metodo di classe.

class MyClass 
     def instance_method 
     puts "instance method" 
     end 

     def self.class_method 
     puts "class method" 
     end 
    end 

che vengono utilizzati in questo modo:

instance = MyClass.new 
    instance.instance_method 

Oppure:

MyClass.class_method 

speranza che cancella le cose un po '.Vedere anche: http://railstips.org/blog/archives/2009/05/11/class-and-instance-methods-in-ruby/

+1

Leggera estensione alla tua risposta: 'def object.my_foo_method'. Definisce 'my_foo_method' su' obj'. Nel contesto della tua risposta, 'self' è l'oggetto della classe' Class' (vale a dire, la classe 'MyClass'). Quindi, definisce il metodo su quella classe. – Swanand

+0

Non dovrebbe essere usato un segno '@' per le istanze, ad es. @ istanza = ...? –

+0

dato che è rotaia e probabilmente sarà usato nella vista –

2
class User 
    def self.xxx 
    end 
end 

è un modo per definire metodo di classe mentre

class User  
    def xxx 
    end 
end 

definirà un metodo di istanza.

Se rimuovi il sé. dal DEF, si otterrà un metodo non trovato errore quando si esegue

User.authenticate 

perché si sta tentando di chiamare un metodo su una classe piuttosto che un'istanza della classe. Per utilizzare un metodo di istanza, è necessaria un'istanza di una classe.

4

self definisce un metodo della classe invece del esempio della classe. Quindi, con def self.authenticate è possibile effettuare le seguenti operazioni:

u = User.authenticate('[email protected]','[email protected]') 

Invece di fare ...

u = User.new 
u.authenticate('[email protected]','[email protected]') 

In questo modo, non c'è bisogno di creare un'istanza di utente per l'autenticazione uno.

+0

Oltre a evitare di dover creare un'istanza di una classe per poter utilizzare un metodo, esistono altri motivi per definire i metodi di classe invece dei metodi di istanza? – LazerSharks

3

Per motivi di completamento e per contrastare il mal di testa in futuro, mi piacerebbe sottolineare, inoltre, che i due sono equivalenti:

class User 
    def self.authenticate 
    end 
end 

class User 
    def User.authenticate 
    end 
end 

questione di preferenze.