この質問は、「MVCの明らかな違反であるため」というような、1行のアサーションで繰り返し尋ねられ、回答されています。率直に言って、私はそれを得ていない。実際、コントローラ内にセッションを置くことは、ApplicationControllerがMVCの命令ではなく、ラック呼び出しを介してネットワークレイヤに向かうアーティファクトにすぎないと感じています。私の問題を説明しましょう。Modelレイヤーでセッションハッシュを参照してみませんか?
認証をゼロから転がすと、簡単なテスト(セッションはテストフレームワークでは利用できません)を明示する能力がないため、苦労して苦労していました。私の認証方式は、ほとんどの場合、セッションのハッシュを永続化レイヤーとして使用して、「現在のユーザー」のUserモデルのIDを保持したかったのです。コントローラーの人工物よりも、まるでモデルのような感じがしませんか?
「典型的な」セッションコントローラ(Ryan Batesの優れたスクリーンキャストからのもの)を見るたびに、コードの匂いがはっきりと分かります。残りの部分とにこの概念をシャベルに必死、私たちのような不健康な言語を参照してください。私には
def create
user = User.find_by_email(params[:session][:email])
if user && user.authenticate(params[:session][:password])
session[:user_id] = user.id
redirect_to root_url, notice: "Logged in!"
else
flash.now.alert = "Email or password is invalid"
render "new"
end
end
を、これはコードのにおい、リファクタリングのために叫んされて明らかにoverlogickedコントローラです!しかし、私たちはできません。どうして?ああ、MVCに違反しているためセッションへの参照を残して、永続化弁護士としてモデルに使用します。 WTF?私たちがこのREST RESOURCE /セッションに電話をかけたいと思うようなことはあなたに何か言っていませんか?
なぜこれが単なる単純であるかを確認するには、ログインビュー(手書きのhtml)、または「_タグ」APIの使用を見てください。このコードを実行するActiveModelモデルがあれば、作成コードは通常の足場のように見えるか、おそらくは「respond_with」の1ライナーに縮小される可能性があります。
def create
recognition = Recognition.new(params[:user])
if recognition.save
redirect_to root_url, :notice => "Thank you for signing up!"
else
render "new"
end
end
次に、これらのすべてのビューの手作業でコーディングされたHTMLを見てみましょう。 Recognitionがセッション(またはコントローラレイヤの責任ではない他の手段)によって保持されているモデルの場合、フォームビルダーまたはsimple_formを使用してフォームを生成することができます。もちろん、単にセッションのハッシュを「new_login」クラスのRecognitionのメソッド、たとえばRecognition.on(session).new(params[:recognition])
に渡すこともできますが、それは必然的に醜いと思われます。アプリケーション層で後でcurrent_user参照を使用したいと思うかもしれませんが、おそらくRecognition.on(session).current_user
はシングルトンパターンを使用する方法に似ていますか?
厳密なBDDを使用して認証パッケージを構築しようとしましたが、正にこの部分をスパイクしていないと教えてください。 Recognitionモデルがあれば、この全体がハッカーのない単体テストの単純なセットに縮小されます。さて、代わりに、統合テストのための "唯一の"ユースケース、ActiveControllerモジュールの魔法の侵入、およびlogged_in_as述語の受け入れテストを迅速に行うためのハッキングがあります。
私はActiveModelの全ポイントがこのような再考とリファクタリングを容易にすると考えていました。すべてのモデルが "the"データベースを使用するわけではありません。どうして、「セッション?
私はあまりにも長い間、この匂いを "宝石と混乱しないでください"という言葉で埋めています。私はそれらを見る必要はありません。もはや!私は今から熱狂者たちを拒絶するつもりだと思う。申し訳ありませんが、セッションは、MVCのModelレイヤーで操作する必要がある持続レイヤーです。コントローラーランドに住んでいる理由は、コントローラーが理論的なMVCの魔法よりもラックオブジェクトであるという醜いエレガントな事実に関係していると思います。
もう一度、セッション層にアクセスするよりエレガントな方法は、コントローラーにロジックを持たせるよりですか?
ありがとうございました。興味深いことに、Railsは、モデル、per_seではなく、あなたが記述する1ライナーに進化しました。コントローラーのメカニックは、実際には、モデルレイヤーの呼び出し後にrespond_withを使用するために3.Xで進化しました。私が提案した変更はコントローラをモデルに還元するのではなく、データベースの永続化されたコンテンツが使用されているのと同じようにコントローラの不要なロジックをモデル呼び出しに減らします。 – wizardwerdna