2013-04-01 5 views
7

鉄道庁はリファクタリングに大きなエピソードを出しました。 1つの方法は、複雑なコントローラロジックをモデルにプッシュするのではなく、サービスオブジェクトに移動することです。 one service objectでは、次のコードが使用されます。このRubyメソッド定義で `new`キーワードはどのように機能しますか?

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 

newキーワードは、両方のメソッド本体に何を提供していますか? new User.find_by_User.find_by_とはどのように違いますか? attr_reader :userが必要な理由、また

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 

は、ここで呼び出し元のコードですか?

+0

@userに応じて設定される

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 

:すべて一緒にそれを置く、あなたはとしてそれを書かれている可能性があなたが知りたい実際の質問ですか?彼らは魅力的な餌を使ってより多くの魚を捕まえます。 –

答えて

10

classnameは自己メソッドに暗黙的に指定されています。 (あなたはJavaやC#から来ている場合はgetterメソッド別名)attr_readerは、インスタンス変数とリーダーメソッドを定義して、あなたの質問の後半に答えるために

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

:コードは次のように書かれている可能性が。これはPasswordReset#は初期化と仮定することは、ONEを反映しているので、あなたがタイトルを書き換えることができ、パラメータとしてユーザーを取り、

+1

@dae、User.find_by_email(email)はPasswordResetコンストラクタの引数です。 – Fivell

+0

私は今理解しています。ありがとうございました。しかし、あなたがインスタンス化するよりもオブジェクトをインスタンス化しているのは変です。このパターンの名前はありますか、それとも正常ですか?申し訳ありませんが、私は遅い知っています。私はRubyで考えるのに慣れていないと思います。 'attr_reader'が' @ user'または 'nil'を返すと仮定します。インスタンス内で 'user'と呼ばれるものを探しますか? – dee

+2

コードレビューでは、裸の 'new'を使用することは直感的ではないと主張しています。サポートしている誰もが、何が起きているのかを見るために、メソッド全体、クラスを読むようにしています。 'PasswordReset.new'の使用ははるかに明確で、自己文書化しています。括弧内のパラメータを使った 'new(...)'も改善されていますので、コードを書いた人は-1、クリーナ/明確な解決策を提案するには+1です。 –

関連する問題