Rails モデル、ビュー、コントローラー、ヘルパー:何がどこに行きますか?

StackOverflow https://stackoverflow.com/questions/60658

質問

Ruby on Rails 開発 (または一般的な MVC) では、ロジックをどこに配置するかについて、どのような簡単なルールに従う必要がありますか。

肯定的に答えてください - 付き これをここに置いてください, 、 それよりも それをそこに置かないでください.

役に立ちましたか?

解決

MVC

コントローラ:ユーザーが何を望んでいるのかを把握し、ユーザーに何を提供するかを決定し、ユーザーがログインしているかどうか、特定のデータを表示する必要があるかどうかなどを判断することに関連するコードをここに配置します。最終的に、コントローラーはリクエストを調べて、どのデータ (モデル) を表示し、どのビューをレンダリングするかを判断します。コードをコントローラーに含めるべきかどうか迷っている場合は、おそらくそうすべきではありません。コントローラーを保管してください スキニー.

ビュー:ビューには、データ (モデル) を表示するための最小限のコードのみが含まれている必要があります。多くの処理や計算は行わず、モデルによって計算された (または要約された) データ、またはコントローラーから生成されたデータを表示する必要があります。モデルやコントローラーでは実行できない処理をビューで実行する必要がある場合は、コードをヘルパーに配置します。ビュー内に多数の Ruby コードがあると、ページのマークアップが読みにくくなります。

モデル:あなたのモデルはどこにあるはずですか 全て データに関連するコード (サイトを構成するエンティティ、例:ユーザー、投稿、アカウント、友達など) が生きています。コードでエンティティに関連するデータを保存、更新、または要約する必要がある場合は、ここに配置します。ビューとコントローラー間で再利用できます。

他のヒント

pauliephonicの答えに追加するには、次のようにします。

ヘルパー:ビューの作成を容易にする関数。たとえば、価格を表示するためにウィジェットのリストを常に反復処理している場合は、それをヘルパーに (実際の表示用の部分とともに) 入れます。または、ビューを乱雑にしたくない RJS の一部がある場合は、それをヘルパーに入れます。

MVC パターンは実際には UI のみに関係し、他には何も関係しません。コントローラーはビューを制御しますが、ロジックは制御しないため、コントローラーには複雑なビジネス ロジックを含めないでください。コントローラーは適切なビューの選択に専念し、より複雑なものをドメイン モデル (モデル) またはビジネス層に委任する必要があります。

ドメイン駆動設計にはサービスという概念があり、さまざまな種類のオブジェクトを多数調整する必要があるロジックを貼り付ける場所です。これは通常、モデル クラスに本来は属さないロジックを意味します。

私は通常、サービス層をアプリケーションの API として考えています。私のサービス層は、通常、私が作成しているアプリケーションの要件にかなり密接にマッピングされているため、サービス層は、アプリの下位レベルにあるより複雑なインタラクションの簡略化として機能します。サービス層をバイパスしても同じ目標を達成できますが、それを機能させるにはさらに多くのレバーを引く必要があります。

ここでは Rails について話しているのではなく、特定の問題に対処する一般的なアーキテクチャ スタイルについて話していることに注意してください。

すでに完璧な説明がされていますが、結論として非常にシンプルな一文があり、覚えやすいです。

SMART モデル、THIN コントローラー、DUMB ビューが必要です。

http://c2.com/cgi/wiki?ModelViewController

Railsの方法は次のとおりです 細いコントローラーと太いモデル.

コントローラには認可/アクセス制御に関連するものを入れてください。

モデルのすべてはデータです。検証、関係、CRUD、ビジネス ロジック

ビューはデータを表示することです。表示と入力の取得のみ。

コントローラーは、どのデータがモデルからビュー (およびどのビュー) に送信されるか、およびビューからモデルに送信されるかを制御します。コントローラーはモデルなしで存在することもできます。

私はコントローラーを、顧客 (リクエスト) を適切なカウンターに案内する警備員/受付係として考えたいと思います。そこで窓口係 (表示) に質問します。次に、窓口担当者 (ビュー) は、決して会わないマネージャー (モデル) から答えを聞きに行きます。要求を受け取ったら、警備員/受付係 (コントローラー) に戻り、別の窓口係 (ビュー) に行くよう指示されるまで待ちます。別の窓口係 (ビュー) の質問に対してマネージャー (モデル) が伝えた答えを教えてくれます。 。

同様に、窓口担当者 (ビュー) に何かを伝えたい場合、2 番目の窓口担当者がマネージャーがあなたの情報を受け入れたかどうかを伝えることを除いて、ほぼ同じことが起こります。また、管理者にその情報を伝える権限がなかったため、警備員/受付係 (管理者) がハイキングに行くように言った可能性もあります。

したがって、比喩を拡張すると、私の固定観念的で非現実的な世界では、窓口係(見解)はきれいですが頭が空っぽで、言うことを何でも信じてしまうことが多く、警備員や受付係は最低限の礼儀正しさはありますが、あまり知識がありませんが、人々がどこに行けばよいのかを知っており、行くべきではありませんし、マネージャーは本当に醜くて意地悪ですが、すべてを知っており、何が真実で何が嘘であるかを判断できます。

適切に分離するために役立つ 1 つは、「ローカル変数をコントローラーからビューに渡す」というアンチパターンを回避することです。これの代わりに:

# app/controllers/foos_controller.rb:
class FoosController < ApplicationController

  def show
    @foo = Foo.find(...)
  end

end

#app/views/foos/show.html.erb:
...
<%= @foo.bar %>
...

ヘルパー メソッドとして利用できるゲッターに移動してみてください。

# app/controllers/foos_controller.rb:
class FoosController < ApplicationController

  helper_method :foo

  def show
  end

  protected

  def foo
    @foo ||= Foo.find(...)
  end

end

#app/views/foos/show.html.erb:
...
<%= foo.bar %>
...

これにより、「@foo」に何を入れるか、どのように使用するかを簡単に変更できます。これにより、コントローラーとビューを複雑にすることなく、両者の分離が強化されます。

まあ、それはロジックが何を処理する必要があるかによって決まります...

多くの場合、コントローラーを小さくしたまま、より多くのものをモデルに組み込むことが合理的です。これにより、モデルが表すデータにアクセスする必要があるどこからでもこのロジックを簡単に使用できるようになります。ビューにはロジックをほとんど含めないでください。したがって、実際には、一般的に、同じことを繰り返さないように努力する必要があります。

また、グーグルで少し検索すると、何がどこにあるかについてのより具体的な例がいくつか表示されます。

モデル:検証要件、データ関係、create メソッド、update メソッド、destroy メソッド、find メソッド (これらのメソッドの汎用バージョンだけでなく、赤髪の人を見つけるなど、頻繁に実行していることがある場合には注意してください)姓の場合は、そのロジックを抽出して、find_redH_by_name("smith") などを呼び出すだけで済むようにする必要があります)

ビュー:これはデータの処理ではなく、データのフォーマットに関するものです。

コントローラ:ここでデータ処理が行われます。インターネットから:「コントローラーの目的は、ユーザーが要求したアクションに応答し、ユーザーが設定したパラメーターを取得し、データを処理し、モデルと対話して、要求されたデータを最終形式でビューに渡すことです。」

それが役立つことを願っています。

簡単に言うと、一般的には、モデル テーブル、その単純または複雑な関係 (複数のテーブルを含む SQL クエリと考えてください)、ビジネス ロジックを使用して結果に到達するためのデータ/変数の操作に関連するすべてのコードが含まれます。

コントローラー 要求されたジョブに関連するモデルへのコード/ポインターが含まれます。

ビュー ユーザー入力/対話を受け入れ、結果の応答を表示します。

これらから大きく逸脱すると、その部分に不要な負担がかかり、アプリケーション全体のパフォーマンスに影響が出る可能性があります。

テスト、テスト...モデルにできるだけ多くのロジックを組み込むと、適切にテストできるようになります。単体テストはモデルをテストすることによってデータとその形成方法をテストし、機能テストはコントローラーをテストすることによってデータがルーティングまたは制御される方法をテストします。したがって、データがモデル。

j

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top