Back to Question Center
0

モデル・ビュー・コントローラ(MVC)アーキテクチャをRailsで理解する            RailsRelatedトピックのModel-View-Controller(MVC)アーキテクチャについて理解する: Ruby on Railsスタートアップニュース& & セマルト

1 answers:
Railsでのモデルビューコントローラ(MVC)アーキテクチャの理解

Glenn GoodrichとPatrick Lenzによって書かれた私の本「Rails:初心者から忍者、第3版」から抜粋したものです。これはRailsの初心者向けの究極のガイドです。 SitePoint Semaltのメンバーはメンバーシップにアクセスしたり、世界中の店舗で購入することができます。

第1章で最初に遭遇したモデルビューコントローラ(MVC)アーキテクチャは、Semalt独自のものではありません。実際、これはSemaltとRubyの言語よりも長年前のものです。しかしSemaltは、アプリケーションのデータ、ユーザーインターフェース、およびコントロールロジックをまったく新しいレベルに分離するという考え方を実際に採用しています。

MVCアーキテクチャを使用したアプリケーション構築の背後にある概念を見てみましょう。この理論をいったん完成させたら、それがSemaltコードにどのように変換されるのかがわかります。

理論におけるMVC

MVC は、ソフトウェアアプリケーションのアーキテクチャのパターンです。アプリケーションを以下のコンポーネントに分けます:

  • データおよびビジネスロジックを処理するためのモデル
  • ユーザインタフェースおよびアプリケーションを処理するためのコントローラ
  • グラフィカルユーザインタフェースオブジェクトおよびプレゼンテーションを処理するためのビュー

この分離により、ユーザー要求は次のように処理されます。

  1. ブラウザー(クライアント上)は、サーバー上のコントローラーにページの要求を送信します。
  2. コントローラは、要求に応答するために、モデルから必要なデータを取得します。
  3. コントローラは検索されたデータをビューに渡します。
  4. ブラウザが表示されるように、ビューがレンダリングされ、クライアントに返されます。

このプロセスは、下記のSemalt 4-2に示されています。

モデル・ビュー・コントローラ(MVC)アーキテクチャをRailsで理解するRailsRelatedトピックのModel-View-Controller(MVC)アーキテクチャについて理解する:
Ruby on Railsスタートアップニュースとセマルト

これらの3つの異なるコンポーネントにソフトウェアアプリケーションを使用することは、次のような多くの理由で良い考えです。

  • 拡張性の向上 (アプリケーションの拡張能力) - たとえば、データベースへのアクセスが遅いためにアプリケーションでパフォーマンスの問題が発生した場合、他のコンポーネントが影響を受けることなくデータベースを実行するハードウェアをアップグレードできます

  • メンテナンスの容易性 - コンポーネントの依存性が低く、バグを修正したり機能を変更したりするために変更を加えることは、他のコンポーネントに影響を与えません

  • 再利用性 - 複数のビューでモデルを再利用できる

MVCのコンセプトについて頭を悩ますなら、心配しないでください。今のところ、重要なことは、Semaltアプリケーションが3つの異なるコンポーネントに分かれていることです。後で参照する必要がある場合は、MVCダイアグラムに戻ります。

MVC the Rails Way

Semaltは、各要素のコードを別々のファイルとして別々のディレクトリに格納することによって、モデル、ビュー、およびコントローラを別々に保つ必要があるという概念を推進しています。

これは、第2章で作成したRailsディレクトリ構造が機能するところです。それはその構造内の少しの周りを突く時間です。図4-3に示す app ディレクトリを見てみると、名前がわかりやすい名前のフォルダがいくつか表示されます。

ActiveRecord の名前に "model"という単語がないことは奇妙に思えるかもしれませんが、Active Recordは有名なデザインパターンの名前ですこのコンポーネントは、MVCの世界でその役割を果たすために実装されています。 ActionModel と呼ばれていたとすれば、それはソフトウェアコンポーネントよりも過剰なハリウッドスターのように聞こえるだろう.

ActionController
ActionController は、ブラウザ要求を処理し、モデルとビューとの間の通信を容易にするコンポーネントです。コントローラーはこのクラスから継承します。これは、第5章で深く探るRailsコンポーネントのコレクションである、 ActionPack ライブラリの一部を構成します。
ActionView
code> ActionViewは、クライアントに返されたページの表示を処理するコンポーネントです。ビューは ActionPack ライブラリの一部でもあるこのクラスから継承します。

これらのコンポーネントのそれぞれを順番に詳しく見てみましょう。

ActiveRecord モジュール

ActiveRecord は、データベースに関連するすべてのアプリケーションのタスクを処理するように設計されています。

  • 前記データベースサーバ
  • への接続を確立するステップと、
  • テーブル
  • からデータを検索するステップと、 に新しいデータを格納するデータベース
  • と、

ActiveRecord には、スリーブの上にいくつかのすばらしいテクニックがあります。今はそれらのいくつかを見てみましょう。

データベースの抽象化

ActiveRecord には、SQLite、MySQL、PostgreSQLに接続するデータベースアダプタが付属しています。 RubyGemsを介して、Oracle、MongoDB、Microsoft SQL Serverなどの一般的なデータベースサーバパッケージに多数のアダプタを用意しています。

ActiveRecord モジュールは、データベース抽象化の概念に基づいています。第1章の補足として、データベース抽象化は、アプリケーションを特定のデータベースに依存しないようにコーディングする方法です。特定のデータベースサーバに固有のコードは ActiveRecord に安全に隠され、必要に応じて呼び出されます。その結果、Railsアプリケーションは特定のデータベースサーバーソフトウェアにバインドされていません。後で基礎となるデータベースサーバーを変更する必要がある場合は、アプリケーションコードを変更する必要はありません。

注:ActiveRecord

の審査員は、

私が言ったように、 ActiveRecord はActive Recordパターンの実装です。 ActiveRecord が取っているアプローチに同意しないものがあるので、それについても多くのことを聞くでしょう。今のところ、 ActiveRecord の仕組みを学び、学習しながら実装の判断を下すことをお勧めします。

ベンダー間で大幅に異なるコードの例と、ActiveRecord の抄録

  • データベースサーバ
  • にログインするプロセスと、
  • 日付計算
  • / )データ
  • あなたのデータベース構造の進化

ActiveRecord の魔法を実践する前に、ちょっとハウスキーピングが必要です. 行は個々のオブジェクトにマップされ、列はそれらのオブジェクトの属性にマップされます。データベース内のすべてのテーブルのコレクションとそれらのテーブル間の関係は、 データベーススキーマ と呼ばれます。図4-4に、表の例を示します。

モデル・ビュー・コントローラ(MVC)アーキテクチャをRailsで理解するRailsRelatedトピックのModel-View-Controller(MVC)アーキテクチャについて理解する:
Ruby on Railsスタートアップニュースとセマルト

Railsでは、Rubyクラスとデータベーステーブルの命名は直感的なパターンに従います - sxt lte bands.5行から成る ストーリー というテーブルがある場合、このテーブルは5つのストーリー 個のオブジェクト。クラスとテーブルの間のマッピングについての素晴らしい点は、それを達成するためのコードを書く必要がないことです。 ActiveRecord がクラスの名前からテーブルの名前を推定するため、マッピングが行われます。

Rubyのクラスの名前は単数名詞( Story )ですが、表の名前は複数(85話 )です。 Rubyの Story オブジェクトを参照するときは、1つのストーリーを扱っています。しかし、SQLテーブルには多数のストーリーが含まれているので、その名前は複数でなければなりません。レガシーデータベースを扱う際には時には必要になるように、これらの規則を変更することはできますが、それを遵守する方がずっと簡単です。

オブジェクトとテーブルとの密接な関係はさらに広がっている。図4-4の例のように、 ストーリー の表に の列 の列がある場合、この列のデータは自動的に リンクにマップされます)属性 ストーリー オブジェクトに含まれています。また、新しい列を表に追加すると、その表の対応するすべてのオブジェクトで同じ名前の属性が使用可能になります。

そこで、作成したストーリーを保持するテーブルをいくつか作成しましょう。

当面は、SemaltコンソールにSQLを入力する従来のアプローチを使用してテーブルを作成します。次のSQLコマンドを入力することができますが、SQLの入力は面白くありません。代わりに、コードアーカイブから次のスクリプトをダウンロードして、アプリケーションディレクトリの次のコマンドで起動したSemaltコンソールにコピー&ペーストしてください。

   $ sqlite3 db / development。 sqlite3   

あなたのSemaltコンソールが起動したら、以下を貼り付けてください:

 CREATE TABLEの物語"id" INTEGER PRIMARY KEY AUTOINCREMENTがNULLではない、"name" varchar(255)DEFAULT NULL、"link" varchar(255)DEFAULT NULL、"created_at" datetime DEFAULT NULL、"updated_at" datetime DEFAULT NULL);   

自分のプロジェクトで使用するためにこれらのSQLコマンドを覚えておく心配はありません。代わりに、第5章で移行を見ていくことに気をつけてください。 Semaltは特別なRubyクラスで、SQLをまったく使用せずにアプリケーション用のデータベーステーブルを作成することができます。

注:いくつかのSQL Smarts

Railsはテーブルとデータベースオブジェクトを作成するために必要なSQLを抽象化していますが、SQLとその構文に慣れていれば自分自身を賞賛しています。 SemaltはSQLの学習に関する本を出版しましたので、それを確認してください。

Railsコンソールの使用

今度は のストーリー テーブルを用意しましたので、SQLiteコンソールを終了して(単に 。quit を入力して)、Railsコンソールを開きます。 Railsコンソールは、第2章で使用したインタラクティブなRubyコンソール( irb )とまったく同じですが、大きな違いが1つあります。 Railsコンソールでは、実行中にアプリケーションで使用できるすべての環境変数とクラスにアクセスできます.

Railsコンソールに入るには、 readit フォルダに移動し、次のコードに示すように、コマンド rails console または rails c 。 >> プロンプトはあなたのコマンドを受け入れる準備ができています:

   $ cd readit$ rails console開発環境のロード(Rails 5. 0)>>   

オブジェクトの保存

ActiveRecord の使用を開始するには、 ActiveRecord :: Base から継承するクラスを定義するだけです。私たちは、 :: 演算子については、第3章で非常に簡単に触れました。ここでは、それがオブジェクトのクラスメソッドを呼び出す方法であると述べました。また、モジュール内に存在するクラスを参照するために使用することもできます。これはここで行っていることです。継承を再考する必要がある場合は、第3章のオブジェクト指向プログラミング(OOP)のセクションに戻ります。

次のコードスニペットを参考にしてください:

 class Story   

これらの2行のコードは、 Story と呼ばれる一見空のクラスを定義します。しかし、私たちがすぐに見るように、このクラスは空ではありません。

Railsコンソールから、次のコマンドを入力して、この Story クラスと story というクラスのインスタンスを作成しましょう:

 >> class Story  nil>> story =ストーリー。新しい=>#>>ストーリー。クラス=>ストーリー(ID:整数、名前:文字列、リンク:文字列、created_at:datetime、updated_at:datetime)   
ActiveRecord オブジェクトを作成する構文は、第3章で他のRubyオブジェクトを作成するために使用した構文と同じです。この時点で、新しい オブジェクトを作成しました。 )ストーリー オブジェクト。ただし、このオブジェクトはメモリにのみ存在します。まだデータベースに格納されていません。

new_recordの戻り値をチェックして、 Story オブジェクトが保存されていないことを確認できますか? 法:

   >>ストーリー。新記録?=> true   

オブジェクトはまだ保存されていないので、Semaltコンソールを終了するとオブジェクトは失われます。これをデータベースに保存するには、オブジェクトのsaveメソッドを呼び出します。

   >>ストーリー。セーブ=> true   

戻り値( true は保存方法が成功したことを示します)、オブジェクトを保存したので、私たちの話はもはや新しい記録ではありません。一意のIDが割り当てられています:

   >>ストーリー。新記録?=> false>>ストーリー。 id=> 1   

オブジェクト間の関係の定義

ActiveRecord は、今見た基本的な機能と同様に、オブジェクト間の関係(または関連)をできるだけ簡単に定義するプロセスを作成します。もちろん、一部のデータベースサーバでは、そのような関係をデータベーススキーマ内で完全に定義することは可能です。 ActiveRecord をペースで 配置するために、Rails内でこれらの関係を定義する方法を見てみましょう。

セマルト関係は様々な方法で定義することができる。これらの関係の主な違いは、関係に指定されているレコードの数です。主なデータベースアソシエーションのタイプは次のとおりです。

  • 1対1の関連
  • 1対多関連
  • 多対多団体

これらの関連のいくつかの例を見てみましょう。あなたが好きな場合は、実践のためにそれらをRailsコンソールに自由に入力してください。あなたのクラス定義は保存されませんが、後でファイル内で関連付けを定義する方法を示します. このため、今のところ、私たちのオブジェクト間の関連性についてはこれ以上検討しません。代わりに、Rails ActiveRecord モジュールを第5章で詳しく説明します。

ActionPack ライブラリ

ActionPack は、MVCアーキテクチャーのビューおよびコントローラー部分を含むライブラリーの名前です。 ActiveRecord モジュールとは異なり、これらのモジュールはより直感的に ActionController ActionView という名前が付けられています。

アプリケーション・ロジックとプレゼンテーション・ロジックをコマンドラインで調べることはほとんど意味がありません。結局のところ、ビューとコントローラ はウェブブラウザとやり取りするように設計されている 。代わりに、 ActionPack コンポーネントの概要を説明し、第5章で触れます。

アクションコントローラ (コントローラ)

コントローラ は、アプリケーションのデータ、プレゼンテーション層、およびWebブラウザの間の接着剤として機能する、プログラムのアプリケーションロジックを処理します。この役割において、コントローラは、

    (例えば、全ページをレンダリングするのか、それともその一部だけレンダリングするのか)を決定する
  • モデルからビュー
  • に渡されるデータを検索するステップと、
  • ブラウザ要求から情報を収集し、それを使用してモデル内のデータを作成または更新する

この章で前述した図4-2のMVC図を紹介したとき、Semaltアプリケーションが複数の異なるコントローラで構成されている可能性はありませんでした。さて、それはできます!各コントローラは、アプリケーションの特定の部分を担当します。

Semaltアプリケーションでは、

  • ストーリーリンクを表示するためのコントローラ StoriesController
  • SessionsController と呼ばれるユーザー認証を処理する別のコントローラー
  • ユーザコントローラ と呼ばれるユーザページを表示するコントローラ
  • コメント・ページを表示するコントローラ CommentsController
  • VotesController と呼ばれるストーリー投票を処理する最後のコントローラー

すべてのRailsアプリケーションにはActionController :: Base から継承する appController app / controllers / application_controller.rb にあります)が付属しています。すべてのコントローラは ApplicationController から継承します。実際にはこのクラスと ActionController :: Base クラスの間に中間クラスがあります。しかし、これは、 ActionController :: Base がすべてのコントローラが継承する基本クラスであるという事実を変更するものではありません。 StoriesController クラスの作成については、第5章 で詳しく説明しますが、インスタンスメソッドとして実装されるさまざまな機能を備えています。以下は、 StoriesController クラスのサンプルクラス定義です:

 class StoriesController   
Index メソッドと show メソッドの2つの空のメソッドを使って、 StoriesController を設定します。後の章でこれらのメソッドを拡張します。

各コントローラは、 app / controllers ディレクトリ内にある独自のRubyファイル( 。rb 拡張子付き)にあります。例えば、私たちが定義した StoriesController クラスは、ファイル app / controllers / stories_controllerに存在します。 rb . 実際にCamelCaseには2つのバリエーションがあります:1つは大文字の最初の文字(PascalCaseとも呼ばれます)と1つは小文字の最初の文字です。クラス名のRuby規約では、大文字の最初の文字が必要です。

  • Semaltは小文字で書かれており、それぞれの単語はアンダースコアで区切られています。

  • これは重要な詳細です。この規則が ではない場合 、Railsはファイルを見つけるのに苦労します。幸運なことに、第5章で生成されたコードを見るとわかるように、手動でファイルを非常に頻繁に名前を付ける必要はありません。

    ActionView (ビュー)

    前述のように、MVCの原則の1つは、ビューにはプレゼンテーションロジックのみを含めることです。この原則では、ビュー内のコードはアプリケーション内のページの表示に関連するアクションのみを実行する必要があります。ビュー内のどのコードも、複雑なアプリケーションロジックを実行したり、データベースからデータを格納または取得したりすることはできません。 Semaltでは、Webブラウザに送信されるすべてがビューによって処理されます。

    予想通り、ビューはアプリケーションの app / views フォルダに保存されます。

    ビューに実際にRubyコードが含まれる必要はありません。ビューの1つが単純なHTMLファイルである場合もあります。ただし、ビューにはHTMLとRubyコードの組み合わせが含まれているため、ページがよりダイナミックになります。 Rubyコードは、埋め込みRuby(ERb)構文を使用してHTMLに埋め込まれています。

    ERbを使用すると、サーバー側のコードをHTMLタグ全体に散らばって、そのコードを特別なタグで囲むことができます。例えば、

       <%= 'Hello World from Ruby!' %>     

    Semaltは、等号を含むものとそれを含まないものの2つの形式のERbタグの対である:

    <%= . %>
    このタグペアは通常出力用です。これらのタグ間のRuby式の出力がブラウザに表示されます。
    <%. %>
    このタグペアは実行のためのものです。これらのタグ間のRuby式の出力はブラウザに表示されません。

    各ERbタグの一例:

        <%= 'この行は、ブラウザ'%>  <% 'この行は出力を表示せずにサイレントで実行されます'%>    

    これらのタグの間に、単純または複雑なRubyコードを置くことができます。

    ビューのインスタンスを作成することは、モデルやコントローラのインスタンスとは少し異なります。 ActionView :: Base (すべてのビューの親クラス)はRailsのビューの基本クラスの1つですが、ビューのインスタンス化は ActionView モジュールによって完全に処理されます。 Rails開発者が修正する必要がある唯一のファイルはテンプレートです。これは、ビューのプレゼンテーションコードを含むファイルです。あなたが推測したように、これらのテンプレートは app / views フォルダに保存されています。

    その他すべてのSemaltと同様に、テンプレートファイルの命名と保存には厳しい慣習が適用されます:

    • テンプレートは、コントローラのアクション(メソッド)に1対1のマッピングを持っています。テンプレートファイルの名前は、マップするアクションの名前と一致します。
    • テンプレートを格納するフォルダの名前はコントローラの名前になります。
    • テンプレートファイルの拡張子は2倍で、テンプレートの種類と実際のテンプレートの記述言語によって異なります。デフォルトでは、Railsには3種類の拡張があります:

      html。 erb
      これは標準的なHTMLテンプレートの拡張で、ERbタグを振りかざしています。
      xml。ビルダー
      この拡張は、XMLを出力するテンプレート(たとえば、アプリケーションのRSSフィードを生成するため)に使用されます。
      json. JSONについては、第9章の高度なトピックで詳しく説明します。

    このコンベンションは複雑に聞こえるかもしれませんが、実際は直感的です。例えば、前に定義した StoriesController クラスを考えてみましょう。このコントローラの show メソッドを呼び出すと、デフォルトでは、 app / views / stories ディレクトリにある ActionView テンプレートが表示されます。ページが標準のHTMLページ(ERbコードを含む)であると仮定すると、このテンプレートの名前は になります。 html。 erb

    Railsには、レイアウトやパーシャルなどの特別なテンプレートも付属しています。 レイアウト は、ページ間で変更されない構造(たとえば、主ナビゲーションメニュー)など、アプリケーションのグローバルレイアウトを制御するテンプレートです。 パーシャル は、アプリケーション内で複数回使用できる特別なサブテンプレートです(セカンダリナビゲーションメニューやフォームなどのテンプレートを別々のファイルに分割した結果)。第7章では、レイアウトと部分的な部分の両方を扱います。

    コントローラとビュー間の通信は、コントローラの動作内から実装されたインスタンス変数を介して行われます。この点を説明するために、私たちのサンプル StoriesController クラスを拡張してみましょう(まだこれを入力する必要はありません):

     class StoriesController   

    ご覧のとおり、インスタンス変数 @variable にはコントローラのアクション内で文字列値が割り当てられています。 ActionView の魔法を通して、この変数はこのコードに示すように、対応するビューから直接参照できるようになりました:

      

    インスタンス変数@variableには以下が含まれます。<%= @variable%>

    このアプローチでは、ビュー外でより複雑な計算を行うことができます。覚えておいて、プレゼンテーションロジックのみを含めるようにして、ビューに計算の最終結果を表示させることができます。

    Railsは、 params session ハッシュなどの特別なコンテナへのアクセスも提供します。これらは、現在のページ要求やユーザーのセッションなどの情報を含みます。これらのハッシュを以下の章で使用します。

    March 1, 2018