JavaからのRuby on Rails入門

Ruby on Railsの基本中の基本 MVC + ルーターについて

calendar

reload

スポンサーリンク

MVCパターン

 Ruby on Railsは、MVCパターンと呼ばれるアーキテクチャを採用しています。

 MVCというのは、

  • Model(モデル)
  • View(ビュー)
  • Controller(コントローラー)

の略で、ユーザーインタフェースをもつアプリケーションソフトウェアを実装するためのデザインパターンのことを言います。

 と説明されてもよく分からん。という人に向けて書きます。長いです。

コントローラーとは

 コントローラーはまさにコントローラーです。司令塔です。

 コントローラーの命令に従って、モデルとビューが働きます。コントローラーの命令無しでは何も動きません。

 モデルとビューに命令を出すのがコントローラーの仕事です。

 そういう意味では、コントローラーは意思決定をする上司みたいなものと言えます。

モデルとは

 モデルとは、データを司る存在です。

 コントローラーからの命令に従って、データベースから必要な情報を取り出してコントローラーにその情報を返したり、あるいは、コントローラーの命令に従って、データベースに情報を書き込んだり、書き換えたりします。

 データベースを直接触れるのはモデルだけです。奥にこもって黙々と作業する職人さんみたいなイメージです。コントローラーの言うとおりに働きます。

ビューとは

 ビューとは、デザイン及びユーザーインターフェースを司る存在です。

 コントローラーから渡されたデータを使って、どういうhtmlページを表示するかをビューで定義します。

 もちろん見た目だけの問題ではありません。入力フォームなどのユーザーが触れる部分を正しく機能するように設置するのもビューの仕事です。 

 ユーザーと直接やりとりするのはビューだけです。

 ビューはお客さんに対応する窓口担当のような役割を持っています。笑顔でお客様に対応しながらも、背後から上司(コントローラー)にいろいろ命令されています。

ルーターとは

 Railsでは、コントローラー、モデル、ビューとは別に、Router(ルーター)という重要な役割があります。

 ルーターは、役割的にはコントローラーの一部と言えます。

 webというのはクライアント側からのhttpリクエストに対するサーバー側からのレスポンス、その応酬で成り立っておりますが、ルーターがしているのは、そのhttpリクエストを読み取って、処理を振り分けるという役割です。

 コントローラーが社長だとすると、ルーターはその秘書・取り次ぎ役みたいなものです。「社長、こんなリクエストが来ました」って。

MVCを実装してみる

 抽象的な説明ではイメージはつかめても、いまいちピンと来ないと思うので具体的な話に移りましょう。

 コントローラー、モデル、ビューは、それぞれファイルとして然るべきディレクトリに配置されます。

mvc 画面左のファイルツリーを確認してみてください。appディレクトリ下に、controllers、models、viewsと言う名前のディレクトリが既にあるのが分かると思います。

 ディレクトリ名が複数形になっているように、コントローラー、モデル、ビューというのはそれぞれ一つずつではなく、普通は複数存在します。それらをまとめて置いておくのがcontrollers、models、viewsディレクトリです。

 現状ではそれぞれのディレクトリの中身はデフォルト状態の必要最低限のものしかありません。これから、このアプリケーション独自のファイル(コントローラー、モデル、ビュー)を作成していきます。

作りたいページと情報

 さて、これから電話帳アプリを作るわけですが、具体的にどんなものなのか説明しておきます。

 メンバーごとに登録できる情報は、

  • 名前
  • よみがな
  • 電話番号

 これだけです。分かってるとは思いますが、全くもって実用的な代物じゃないのでそのつもりでお願いします。
 日本語というのは不便なもので、五十音順にソートしようと思えば、必ずよみがなが要ります。

 必要なページは、以下の3つです。

  • 一覧ページ http://ドメイン/members
  • 新規登録ページ http://ドメイン/members/new
  • 編集ページ http://ドメイン/members/:id/edit

 メンバーの一覧ページと、新たにメンバーを登録するページ、登録したメンバーの情報を編集するページです。

 編集ページurlの、:idというのは、表示したい人のIDを意味しています。
 例えば、IDが1の人の編集ページのurlは、
http://ドメイン/members/1/edit
となります。

 編集ページというのは、誰か一人のデータを編集するページなので、その人ごとにページが存在することになります。つまり登録した人数分のページが必要です。リクエスト(url)の中にIDを含むことで、各々の編集ページを動的に表示します。

 membersというのは言わばリソース名です。

 電話帳アプリというのは、言い方を変えるとmembersリソースを管理する為のアプリだと言えます。membersリソースを管理する為に、上記の3つのページを用意するわけです。

ルーターでHTTPリクエストを捌く

 上記のようにHTTPリクエスト(url)ごとに処理を分けるには、まずルーターを編集する必要があります。

/config/routes.rbが、ルーターと呼ばれるファイルです。開いて下さい。
routes_rb

 ルーターがすることは、クライアントからのHTTPリクエストを読み取って、コントローラーへと取り次ぐという仕事です。

 デフォルトでは、

 ↑このようにdoブロックの中身は英語でコメントが書いてあるだけで、空っぽです。
 このdoブロックの中に、コントローラーへの取り次ぎのルールを書いていきます。

 正しく書けたらcommand + sでroutes.rbを保存しましょう。

 Cloud9ではcommand + sでファイルを上書き保存することができます。保存しない限り、プログラムには反映されません。

 インデント(字下げ)は必ず必要です。Rubyの文法においてはインデントはブロックを表します。ちなみにRubyでは字下げは2文字が標準とされています。

 Cloud9では画面右上の方に設定ボタンがあり、そこで字下げの設定を変えることができます。
tabs

 たったこれだけで、以下のHTTPリクエストに対応できるようになります。

 黄色のラインが入っているのが上記で説明した3つのページ(一覧画面、新規作成画面、編集画面)に当たります。

 GET、POST、PATCH、PUT、DELETEというのはHTTPリクエストのメソッドのことです。
 単純にwebページを閲覧する時に使われるメソッドはGETです。GETはサーバー上のファイルを読み込むメソッドです。
 サーバー上のデータを書き換えたりする際のメソッドがPOST、PATCH、PUT、DELETEになります。
 この辺は具体的に使い分ける処理を書くとよく分かってくると思うので、ここではサラッと行きます。

 routes.rbのブロックの中に、resources :membersと書くことで、membersリソースに対する閲覧、編集、削除といったリクエストに一通り対応できる状態になるわけです。具体的な処理内容の定義はコントローラーで行います。

 これで取り次ぎ役(ルーター)は、クライアントから上記のHTTPリクエストが来た場合に、正しく社長(コントローラー)へと取り次げるようになりました。

 ルーターで設定した受け渡しルールのことをルーティングと言います。ルーティングはコンソールで以下のコマンドを打つことで確認することができます。

 コマンドを打つとコンソールに今現在設定されている全てのルーティングが一覧で表示されます。

コントローラーを作る

 「社長、こんなリクエストが来ましたーーー!」と、ルーターが持ってきた客の要望に対して、どういう処理を行うか決定するのが社長(コントローラー)の仕事です。

 では実際に、コントローラーを作ってみましょう。

 前回、rails newコマンドでアプリケーションの土台を一気に作りましたが、同じようにコマンド操作でコントローラーを作ることができます。

 コマンドを打つ前に、cdコマンドで、カレントディレクトリをphone-bookに変更しておきます。

cd_phone-book

 コマンド操作でアプリケーションに関する操作をする際はアプリケーションのルートディレクトリでコマンドを叩く必要があります。workspace自体のルートディレクトリではないので注意しましょう。

 コントローラーは、リソースごとに作ります。

 リソースと言うのはここでいうmembersのことです。現状ではルーターが持ってくるのはmembersに関するリクエストだけなので、とりあえずmembersという名前のコントローラーを作ります。

 コントローラー名は複数形で付けるのがRailsの規約です。

rails g controller コントローラー名
というコマンドで、その名前のコントローラーを作ることが出来ます。

 コンソールに以下のコマンドを入力してエンターを押してください。

 これで以下の5つのファイルと1つの空ディレクトリが作られました。

 一番上のmembers_controller.rbというのがmembersコントローラーです。2番めのapp/views/membersというのは、membersビューを保存するためのディレクトリです。後で出てきます。
 他のファイルはここでは触りません。

 コマンド操作でコントローラー等を作るっていうのは、言ってみれば単にファイルやディレクトリを上記のように新規作成しているだけです。

 自分で全てのファイルを一つ一つ新規作成しても構わないのですが、Railsではファイル名の命名規則があります。ファイルを置く場所(ディレクトリ)にもルールがあります。

 決められたディレクトリに、命名規則に則ったファイルを置くというのがRailsでは重要です。ファイル名やディレクトリ構造こそがRailsシステムの根幹部分を支えています。

$ rails g contoroller members
というコマンド操作で、
members_controller.rb
というファイル名が出来上がったのを見れば分かるように、コントローラーファイルは、

コントローラー名_controller.rb

という命名規則に則っています。この名前のおかげで、このファイルはmembersのコントローラーだということが認識されます。

 コマンド操作で作成すれば、そういったルールに則った形でファイルやディレクトリが作られます。細かい命名規則やそのファイルの配置場所(ディレクトリ)なんかを覚えずとも全て任せてしまえるわけです。

コントローラーを定義する

 では出来上がったmembersコントローラーを見てみましょう。
/app/controllers/members_controller.rbを開いて下さい。

ご覧のように中身はまだ空っぽです。

class名がMembersControllerとなっていますが、これも命名規則に則って作られた名前です。

 まずは、「一覧ページを見せてくれ」というリクエストに対応しましょう。

 一覧ページを見せてくれというリクエストに対しては、indexというアクションが呼ばれます。

 アクションというのは、コントローラーで定義するメソッドのことです。コントローラーでindexというメソッドを定義することで、ルーターからの取り次ぎに対応します。

 こうすることで、「membersの一覧画面を見せてくれ」というHTTPリクエストを受けると、membersコントローラーのindexメソッドが呼ばれる状態になったわけです。

 このメソッドの定義部分にその対応を書きます。

 ここでは、まず仕組みの説明の為に、一覧画面には「Hello」と表示するだけにします。

 この@messageというのは、テンプレート変数と呼ばれるもので、アクションメソッドの中でテンプレート変数に値を格納すると、ビューからもその値を参照することができます。

 つまり、一覧画面を表示する為のビュー(窓口役)に、Helloという文字列を使って、ページを表示しなさい。と命令しているようなものです。

 その情報を使って、どういうページを表示するか決めるのはビューの仕事です。コントローラーがするのは、表示するべきデータを渡すことだけです。

 この分業制度がRailsの肝です。

 このように、membersコントローラーのindexアクションによって、http://ドメイン/membersというページを表示する処理を行っているわけですが、rake routesコマンドで、ルーティングの一覧をもう一度見て下さい。

 2行目がhttp://ドメイン/membersを表示するリクエストに当たりますが、右端のController#Actionの項目がmembers#indexになっているのが分かると思います。

これは、/membersにGETリクエストを送ると、membersコントローラーのindexアクションが呼ばれることを示しています。
※一番左端のPatternの項目については、また次回以降に。

ビューを定義する

 続いて一覧画面を表示するためのビューを作ります。

 ビューはコマンド操作で作ることは出来ないので、普通に作ります。
※後で説明しますが、ここで言っているビューとはテンプレートファイルのことです。

 ファイルツリーの/app/views/membersを右クリック→New Fileをクリックしてください。

view2

 ファイル名は、index.html.erbとします。

 membersコントローラーのindexアクションで使われるビューのファイル名は、
/views/members/index.html.erb
にする必要があります。これもRailsの命名規則の1つです。

 拡張子は.erbになっていますが、これはEmbedded Rubyの略で、htmlの中にRubyスクリプトを埋め込んだファイルのことです。

 erbファイルを使って最終的にhtmlファイルを出力するので、.html.erbとなっています。

view3

 /view/membersindex.html.erbというファイルが出来ました。これがmembersコントローラーのindexアクションで使われるビューです。

 ではこのindex.html.erbを編集して、membersコントローラーの命令通り「Hello」という文字列を表示するようにします。ファイルを開いて下さい。

 書くのはたった一行です。

 <%= %>が、htmlの中にRubyスクリプトを埋め込むための表記です。

 @messageというのは、コントローラーで定義したテンプレート変数です。コントローラーで定義したテンプレート変数はビューからも参照することが出来ます。
 たったこれだけの表記で、コントローラーからの司令を受け取ることが出来るわけです。

 Rubyのスクリプト表記には2種類あります。
<%= %>は、htmlとして出力する場合
<% %>は、評価するだけで出力しない場合

 つまり、

というerbファイル内の表記は、サーバー上で、

というhtmlに変換されてからクライアント側へ送られることになります。

レイアウトテンプレート

 上記では、index.html.erbのことをビューを呼びましたが、index.html.erb単体でビューの機能を果たすわけではありません。

 index.html.erbは、あくまでそのページの一部分を表示するために使われるテンプレートファイルでしかありません。

 ページ全体のhtmlを吐き出すファイルは、
/views/layoutsディレクトリにあるapplication.html.erbです。

layout_template

 このファイルはrails newコマンドで自動作成されたものです。開いてみましょう。

 デフォルト状態で、このように最低限webページの体裁が整う状態になっています。これがページ全体のhtmlの元となります。

 この中で<%= yield %>という表記があると思います(12行目)。このyieldの部分に先程定義したテンプレートファイル(index.html.erb)が挿入される形になります。

 もちろんyieldで読み込まれるのは、それぞれのページ固有のテンプレートファイルです。まだ今のところテンプレートファイルはindex.html.erbしか作っていませんが。

 ページ全体に関わる部分(ヘッダーやフッターなど)はapplication.html.erbで定義し、各ページ固有の内容は各テンプレートファイルで定義するようにすれば、ビューのメンテナンスが非常に楽になります。

 application.html.erbは、レイアウトテンプレート(あるいは単にレイアウト)と呼ばれています。

 サイトの共通部分であるレイアウトテンプレートと、各ページ固有の部分であるテンプレートファイルが統合されることで、ビューとしての仕事をします。

モデルのすること

 ここまでの実装に、モデルは登場していません。モデルは説明することが非常に多いので詳細はまた次回以降に回しますが、どこで何をするのかだけ簡単に説明しておきます。

 コントローラー(members_controller.rb)のindexアクションを思い出して下さい。

 ここではテンプレート変数messageに、「Hello」という文字列を与えていました。そしてそれをビューから参照していたわけですが、ここがモデルの働きどころです。

 「Hello」の例ようにコントローラーで勝手に値を用意するのではなく、モデルに対して「ID番号1のmemberの情報をデータベースから引っ張って来い」と命令して返ってきた値をテンプレート変数に格納する。なんてことが簡単にできるわけです。

 コードの書き方についてはまた次回以降に説明しますが、こんな感じでコントローラーはモデルに対して「この情報持って来い!」と司令を出します。その命令に従ってデータを用意するのがモデルの仕事です。

 そして、モデルに情報を用意させて、ビューにそれを渡す。それが上司であるコントローラーの主な仕事です。

HTTPリクエスト → Router → Controller → Model → Controller → View → レスポンス

mvc_pattern

 この流れをまず理解しましょう。

 さて、長々とやって参りましたが、これでとりあえず

http://ドメイン/members

にブラウザでアクセスすると、「Hello」という文字が表示される状態になりました。

 テストサーバーを立ち上げて確かめてみましょう。
 Railsには標準でテスト用のサーバーがついているので、書いたプログラムを簡単に走らせてみることが出来ます。

分からないことはここで質問してみてください↓

この記事をシェアする

コメント

コメントはありません。

down コメントを残す




関連記事

書いている人

Nobuo

Nobuo

一番かんたんなJava入門というサイトを運営しています。Javaやphpは少し分かりますが、Ruby on Railsについては全く何も知らないので、このサイトにアウトプットしながら覚えていこうかと思っています。 [詳細]

folder Rubyの基本文法

more...

folder 初めてのRuby on Rails入門

more...

folder Rails忘備録

more...