2013-04-01 17 views
7

Railscasts wydały świetny odcinek na temat refaktoryzacji. Jedną z metod jest przeniesienie złożonej logiki kontrolera do obiektów usługowych zamiast przesuwania jej w dół. W one service object używany jest następujący kod:Jak działa słowo kluczowe `new` w tej definicji metody 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 

Co oznacza słowo kluczowe new służyć zarówno organów metoda? new User.find_by_. Czym różni się od User.find_by_?

Oto kod wywołujący:

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 

Również dlatego attr_reader :user potrzebne?

+0

można przepisać tytuł więc odzwierciedla ONE aktualne pytanie, które chcesz wiedzieć? Złowisz więcej ryb przy użyciu przynęty, która ich zdaniem będzie atrakcyjna. –

Odpowiedz

10

nazwa klasy jest niejawna w metodach self. Kod mógł zostać napisany tak:

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

Aby odpowiedzieć na 2. połowę na swoje pytanie, attr_reader definiuje zmienną instancji oraz sposobu Reader (aka metody pochłaniacza Jeśli idziesz z Java lub C#). Składając to wszystko razem, można napisać go jako:

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 

to zakładając PasswordReset # zainicjować przyjmuje użytkownika jako parametr, i ustawia @user odpowiednio

+1

@dae, User.find_by_email (email) jest argumentem dla konstruktora PasswordReset. – Fivell

+0

Teraz rozumiem. Dziękuję Ci. Wydaje się jednak dziwne, że tworzysz obiekt, niż sam się tworzy. Czy istnieje nazwa tego wzoru, czy jest to normalne? Przepraszam, wiem, że jestem wolny. Nie jestem przyzwyczajony do myślenia w Ruby, tak myślę. Zakładam, że 'attr_reader' zwraca' @ user' lub 'nil'? Czy po prostu szuka czegoś zwanego "użytkownikiem" w instancji? – dee

+2

W przeglądzie kodu argumentowałbym nawet, że używanie gołego "nowego" jest nieintuicyjne i zmusza każdego, kto wspiera tę metodę, a może nawet klasę, tylko po to, by zobaczyć, co się dzieje. Używanie 'PasswordReset.new' jest dużo bardziej przejrzyste i samo-dokumentujące. Nawet "nowy (...)" z parametrem w nawiasie byłby poprawą, więc -1 dla każdego, kto oryginalnie napisał kod, i +1 dla sugerowania czystszego/klarowniejszego rozwiązania. –

Powiązane problemy