Ruby ではプレゼンテーション ロジックをコントローラーに入れるのが良い習慣ですか?
-
12-12-2019 - |
質問
いくつかの推奨事項 [1] を使用することをお勧めします。
<%= current_user.welcome_message %>
の代わりに
<% if current_user.admin? %>
<%= current_user.admin_welcome_message %>
<% else %>
<%= current_user.user_welcome_message %>
<% end %>
しかし、問題は、コードのどこかに決定ロジックを含める必要があることです。
私の理解では決定を下すということです template
よりも良い controller
コントローラーをよりクリーンにするためです。それが正しいか?
これを処理するより良い方法はありますか?
解決
私の意見では、変更されるのがテキストだけである場合、それはビューに属しません。ページを再構成する必要がある場合、それがプレゼンテーション ロジックです。これは、データが違うだけです。
他のヒント
このことに疑問を抱くのはあなたが初めてではありません。ビューとコントローラーにロジックがほとんど、またはまったく含まれておらず、モデルがプレゼンテーションに依存しない場合、プレゼンテーション ロジックはどこに属するのでしょうか?
と呼ばれる古いテクニックを使用できることがわかりました。 デコレータパターン. 。アイデアは、プレゼンテーション ロジックを含む別のクラスでモデル オブジェクトをラップすることです。このラッパー クラスは デコレータ. 。デコレーターは、モデルをプレゼンテーションから分離したまま、ビューからロジックを抽象化します。
ドレイパー は、デコレータを定義するのに役立つ優れた宝石です。
あなたが与えたサンプルコードは次のように抽象化できます。
デコレータをビューに渡すには、 @user = UserDecorator.new current_user
コントローラーで。
デコレータは以下のようになります。
class UserDecorator
decorates :user
def welcome_message
if user.admin?
"Welcome back, boss"
else
"Welcome, #{user.first_name}"
end
end
end
そして、あなたのビューには単に次のものが含まれます @user.welcome_message
モデル自体にはメッセージを作成するロジックが含まれていないことに注意してください。代わりに、デコレータはモデルをラップし、モデル データを表示可能な形式に変換します。
お役に立てれば!
これにはヘルパーを使用します。何らかのロケールに基づいてウェルカム メッセージを翻訳する必要があるとします。
の中に app/helper/user_helper.rb
書く
module UserHelper
def welcome_message(user)
if user.admin?
I18n.t("admin_welcome_message", :name => user.name)
else
I18n.t("user_welcome_message", :name => user.name)
end
end
end
そしてあなたのビューでは、次のように書くことができます
<%= welcome_message(user) %>
デコレーター/プレゼンターは非常にクリーンなオブジェクト指向のアプローチを提供しますが、個人的にはヘルパーを使用する方がはるかに簡単で十分であることに注意してください。
いいえ、望んでいません どれでも ユーザークラスにもコントローラーにも条件文はまったくありません。このブログ投稿の例のポイントは、ポリモーフィズム、つまり古き良き OO 設計について言及していることです。
# in application_controller for example
def current_user
if signed_in?
User.find(session[:user_id])
else
Guest.new
end
end
#app/models/user.rb
class User
def welcome_message
"hello #{name}"
end
end
#app/models/guest.rb
class Guest
def welcome_message
"welcome newcomer"
end
end
...お分かりでしょう。
ただし、モデルにプレゼンテーション専用のメソッドを散りばめるのではなく、プレゼンターとして機能するデコレーターを作成します。
require 'delegate'
class UserPresenter < SimpleDelegator
def welcome_message
"hello #{name}"
end
end
そしていま current_user
次のようです:
# application_controller
def current_user
if signed_in?
UserPresenter.new(User.find(session[:user_id]))
else
Guest.new
end
end
ユーザーモデルを装飾し、welcome_message を直接追加します。はい、これにはある時点で何らかの条件ステートメントが含まれる可能性があります。
http://robots.thoughtbot.com/post/14825364877/evaluating-alternative-decorator-implementations-in
答えについては、Presenters の Railscasts エピソードをご覧いただくとよいと思います。
ビュー内のロジックは維持するのが難しいため、ビジネス ロジックをモデルに配置し、すべてのビュー ロジックをヘルパーに配置する必要があります。
コードをオブジェクト指向方式にしたい場合は、デコレータ (オブジェクト指向のヘルパー) を使用してください。
定義するコードを入れます current_user.welcome_message
_app/helpers/application_helper.rb_ にあると、 応用 レイアウト。
別のオプションは、 カスタム ヘルパー モジュール。特定のビューまたはコントローラーに必ずしも関連付けられているわけではありません (以下にリンクしたビデオを参照してください)。 include
その機能を使用したいビュー/コントローラーのモジュールにそれを含めます。
これは白か黒かで決まるものではありません。しかし、あなたが説明したことから、これはapplication_controller.rbに貼り付けるのが邪魔なコードであり、独自のコントローラーを正当化する機能を備えたコードではないようです。最も効果的かつ効率的なオプションは、カスタムヘルパーモジュールを作成することかもしれませんそして、その機能を持たせたいヘルパーにそれを含めます。とはいえ、これは最終的にはアプリケーションの設計者が判断することになります(つまり、 あなた)を決定する必要があります。
ここ のヘルパー モジュールの概要を説明した優れた記事です。 2011 年 5 月
ここ これは RailsCast の概要です カスタム ヘルパー モジュール (つまり、モジュールのようなカスタムは、必ずしも特定のコントローラーまたはビューに関連付けられているわけではありません)。短くて、優しくて、要点を突いています。
そのためのヘルパーメソッドを定義できます。モデル内でウェルカム文を作成するのは良いアイデアではないと思いますが、コントローラーでも同様です。ただし、コードからビューをクリーンにするように努めるべきであり、そのためにヘルパーを使用できる場合は、使用する必要があります。
良い習慣は、実際の View
インスタンス。MVP の Rails パロディ (違いがあります。調べてください) は残念ながら、ビューがテンプレートであるかのように見えます。それは間違いです。
ビューには、MVC および MVC からインスピレーションを得たパターンのプレゼンテーション ロジックが含まれることになっています。また、複数のテンプレートを操作し、モデル層からの状態と情報を表すためにどのテンプレートを使用するかを決定することも想定されています (はい、モデルは ORM インスタンスではなく層です)。
したがって、質問に答えると次のようになります。 プレゼンテーション ロジックはコントローラーには存在しません。