2013-04-01 14 views
7

Railscasts lösten eine große Episode beim Refactoring aus. Eine Methode besteht darin, komplexe Steuerungslogik in Serviceobjekte zu verschieben, anstatt sie in das Modell zu verschieben. In one service object, wird der folgende Code verwendet:Wie funktioniert das Schlüsselwort `new` in dieser Ruby-Methodendefinition?

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 

Was bedeutet das new Schlüsselwort in beiden Verfahren Körper dienen? new User.find_by_. Wie unterscheidet sich das von User.find_by_?

Hier ist der Aufrufcode:

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 

Auch, warum die attr_reader :user benötigt?

+0

können Sie den Titel neu zu schreiben, damit es die ONE reflektiert Aktuelle Frage, über die du dich informieren willst? Sie fangen mehr Fisch mit Köder, die sie ansprechend finden. –

Antwort

10

Der Klassenname ist implizit in Self-Methoden. Der Code könnte werden wie geschrieben:

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

die 2. Hälfte Ihrer Frage zu beantworten, attr_reader definiert eine Instanzvariable und eine Leser-Methode (auch bekannt als Getter-Methode, wenn Sie von Java oder C# kommen). Dass sie alle zusammen, haben Sie es geschrieben könnten:

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 

Dies wird unter der Annahme, password # initialisieren einen Benutzer als Parameter übernimmt und setzt @user entsprechend

+1

@dae, User.find_by_email (email) ist ein Argument für den PasswordReset-Konstruktor. – Fivell

+0

Ich verstehe jetzt. Vielen Dank. Es scheint jedoch merkwürdig, dass Sie ein Objekt instanziieren, als sich selbst instanziiert. Gibt es einen Namen für dieses Muster oder ist es normal? Entschuldigung, ich weiß, ich bin langsam. Ich denke nicht, dass ich in Ruby denke. Ich nehme an, der 'attr_reader' gibt' @ user' oder 'nil' zurück? Sucht es einfach nach etwas, das in der Instanz "Benutzer" genannt wird? – dee

+2

In einem Code-Review würde ich sogar argumentieren, dass die Verwendung des nackten "Neuen" nicht intuitiv ist und jeden zwingt, Unterstützung zu geben, um die ganze Methode und vielleicht sogar die Klasse zu lesen, nur um zu sehen, was vor sich geht. Die Verwendung von 'PasswordReset.new' ist viel klarer und selbstdokumentierend. Sogar "neu (...)" mit dem Parameter in Klammern wäre eine Verbesserung gewesen, also -1 für denjenigen, der den Code ursprünglich geschrieben hat, und +1 für eine sauberere/klarere Lösung. –

Verwandte Themen