2013-04-01 9 views
7

I Railscasts hanno pubblicato un grande episodio sul refactoring. Un metodo consiste nello spostare la logica di controller complessa in oggetti di servizio anziché spingerlo nel modello. Nel one service object, il codice seguente viene utilizzato:Come funziona la parola chiave `new` in questa definizione di metodo Ruby?

class PasswordReset 
    attr_reader :user 

    def self.from_email(email) 
    new User.find_by_email(email) 
    end 

    def self.from_token(token) 
    new User.find_by_password_reset_token!(token) 
    end 
    ... 
end 

cosa significa la parola chiave new servire in entrambi i corpi di metodo? new User.find_by_. Quanto è diverso da User.find_by_?

Ecco il codice chiamante:

def create # controller 
    password_reset = PasswordReset.from_email(params[:email]) 
    if password_reset.user 
     password_reset.send_email 
     redirect_to root_url, notice: "Email sent with password reset instructions." 
    else 
     redirect_to new_password_reset_url, alert: "Email address does not match a user account." 
    end 
    end 

Inoltre, perché il attr_reader :user necessario?

+0

Puoi riscrivere il titolo in modo che rifletta l'ONE domanda reale che vuoi sapere? Potrai catturare più pesci usando l'esca che trovano attraente. –

risposta

10

il nome di classe è implicito nei metodi self. Il codice potrebbe essere scritto come:

def self.from_email(email) 
    PasswordReset.new User.find_by_email(email) 
end 

Per rispondere alla seconda metà della tua domanda, attr_reader definisce una variabile di istanza e un metodo lettore (aka metodo getter se arrivate da Java o C#). Mettere tutto insieme, si potrebbe scrivere come:

class PasswordReset 


    def user 
    @user 
    end 

    def self.from_email(email) 
    PasswordReset.new User.find_by_email(email) 
    end 

    def self.from_token(token) 
    PasswordReset.new User.find_by_password_reset_token!(token) 
    end 
    ... 
end 

Ciò presuppone PasswordReset # inizializzare prende un utente come parametro e imposta di conseguenza @user

+1

@dae, User.find_by_email (email) è l'argomento per il costruttore PasswordReset. – Fivell

+0

Capisco ora. Grazie. Sembra strano, tuttavia, che tu stia creando un'istanza di un oggetto piuttosto che un'istanza stessa. C'è un nome per questo modello o è normale? Scusa, lo so che sono lento. Non sono abituato a pensare in Ruby, immagino. Presumo che 'attr_reader' restituisca' @ user' o 'nil'? Cerca solo qualcosa chiamato 'utente' nell'istanza? – dee

+2

In una revisione del codice, direi che l'uso del nuda 'nuovo' non è intuitivo e costringe chiunque a fare supporto per leggere l'intero metodo, e forse anche la classe, solo per vedere cosa sta succedendo. L'uso di 'PasswordReset.new' è molto più chiaro e autodocumentante. Anche 'new (...)' con il parametro in parentesi sarebbe stato un miglioramento, quindi -1 per chi ha originariamente scritto il codice e +1 per suggerire una soluzione più pulita/più chiara. –