更新日:
【Rails】 MVCフレームワークを初心者向けに丁寧に解説!
MVCフレームワークとは、MVCというデザインパターンを取り入れたフレームワークのことです。
MVCは機能のことではなく、アプリケーションを作成する時にコードを綺麗に保って管理するための考え方のことです。
Ruby on Railsは、プログラミング言語であるRubyで書かれたWebアプリケーションフレームワークですが、MVCというデザインパターンが取り入れられたMVCフレームワークでもあります。
MVCフレームワークの基礎知識
この章では、MVCフレームワークについて解説します。
Ruby on RailsのMVCの流れを理解しよう
Railsアプリケーションは、ルーティング(Routes)→コントローラー(Controller)→モデル(Model)→ビュー(View)の順番で処理が実行されます。
そして、クライアントがリクエストしてからレスポンスを受け取るまでの流れは、次の図の流れになります。
Pikawakaのサイトを検索してから、トップページを表示するまでに内部ではいくつもの処理が実行されているのです。それでは、それぞれの流れを詳しく解説していきます。
リクエストからコントローラーまでの流れ
下記の図の1〜3までがリクエストからコントローラーの流れになります。
今回は、RailsでMVCを理解しやすくする為に、クライアントがリクエストするURLを開発環境でタスク一覧ページを表示させる「localhost:3000/tasks」に変更しています。
クライアントからのリクエスト(❶)はURL(localhost:3000/tasks)としてアプリケーションのルーティング(❷)に届きます。
ルーティングは、送信されたリクエストに対し、どのコントローラーのアクションを動かすのかを設定する場所です。ルーティングのファイル(config/routes.rb)を確認すると、下記のように設定されています。
1
2
# "tasks#index"は、"コントローラー名#アクション名"のこと
get "tasks" => "tasks#index"
このルーティングファイルで設定されている内容は、下記の3つあります。
- get "tasks"の「get」は、HTTPリクエストのGETメソッドを表します。(HTTPメソッドについては、下記の表を参考にして下さい。)
- 「get "tasks"」は、HTTPメソッドのGETで送信される「localhost:3000/tasks」のURLの事です。
- 「"tasks#index"」は、tasksコントローラーのindexアクションを使うことを設定しています。
つまり、「GETで送信されたlocalhost:3000/tasks」に対して「tasksコントローラーのindexアクション」が動くという事をroutes.rbで設定しています。
HTTPリクエスト | 説明 | 例 |
---|---|---|
GET | リソースの取得 | サイトを表示 |
POST | リソースの作成など | 記事の投稿 |
図をもう一度確認するとルーティング(❷)の次は、コントローラー(❸)が動きます。
ルーティングでtasksコントローラーのindexアクションが動くように設定したので、tasksコントローラー(controller/tasks_controller.rb)の中身を確認していきます。
1
2
3
4
5
6
7
8
9
10
class TasksController < ApplicationController
# indexアクションが実行される
def index
@tasks = Task.all
end
# newアクションは実行されない
def new
end
end
routes.rbの「コントローラー名#アクション名」が、tasks_controller.rbの「ファイル名、クラス名、indexアクション」に紐づいている事が分かります。
tasks_controller.rbでは、indexアクションの他にnewアクションも定義されていますが、今回のリクエストではroutes.rbで設定されているのはindexアクションなので実行される事はありません。
コントローラーからデータベースまでの流れ
下記の図の3〜5がコントローラーからデータベースの流れになります。
コントローラー(❸)のアクション内では、モデル(❹)とのやりとりを行ってデータベース(❺)からデータを取得することが出来ます。
タスク一覧ページのリクエスト(localhost:3000/tasks)が送信されているので、データベースに保存されているタスクのデータが必要です。データベースを使ってデータをのやりとりをする場合は、コントローラーの他にモデルを作成しなければいけません。
今回は、下記のコマンドでTaskモデル(model/task.rb)が生成され、Taskモデルに関連付くtasksテーブルが既に存在するものとします。(※この記事ではテーブル作成方法等は省略させて頂きます。)
1
$ rails g model Task (カラム名省略)
tasks_controller.rbをもう一度確認します。
indexアクション内の「Task.all」は、Taskモデル(model/task.rb)のallメソッドを呼び出しています。これは、Taskモデルのallメソッドを利用してtasksテーブルから全てのデータを取得しています。allメソッドは、こちらの【Rails】allメソッドを徹底解説!を参考にして下さい。
1
2
3
4
5
6
class TasksController < ApplicationController
def index
# Taskモデルを通してデータベースからデータを取得させる
@tasks = Task.all
end
end
しかし、Taskモデルが定義されているtask.rbファイルを確認すると、メソッドは一切定義されていません。
1
2
class Task < ActiveRecord::Base
end
これは、TaskクラスがActiveRecord::Baseクラスを継承しているからです。現段階では、ActiveRecord::Baseクラスを継承しているからデータベースとやりとり出来る便利なメソッドが使えているという認識で大丈夫です。
indexアクション内で、「Taskモデルを通し、tasksテーブルに保存してある全データを取得する」という流れは、下記の通りです。
コントローラーからビューまでの流れ
下記の図の6,7がコントローラーとビューの流れになります。
コントローラー(❼)は、モデル(❹)を通してテーブル(❺)から取得したデータを持っています。これをビュー(❼)に渡すことによって、リクエストされたデータを表示する事が出来ます。
では、テーブルから取得したデータをビューに渡すにはどうすれば良いのでしょうか。もう一度コントローラーファイル(controller/tasks_controller.rb)を確認してみましょう。
indexアクション内では、取得したデータを@tasksに代入しています。「@」がついた変数に値を代入すると、ビューファイルに渡す事が出来ます。(@がつく変数はインスタンス変数と呼びます。)
そして、@tasksをビューファイルで展開する事でデータを表示する事が出来ます。
1
2
3
4
5
6
class TasksController < ApplicationController
def index
# Taskモデルを通して、tasksテーブルから取得したデータを@tasksに代入
@tasks = Task.all
end
end
Railsアプリケーションでは、アクションが動いた後、必ずアクション名と同じビューファイル(views/コントローラー名/アクション名.html.erb)が呼び出されます。コントローラーのアクションを定義した際は、必ず同名のビューファイルを作成するのを忘れないようにしましょう。
今回は、tasksコントローラーのindexアクションが動いたので、ビューファイルは「views/tasks/index.html.erb」が呼び出されます。早速ファイルの中身を確認していきましょう。
1
2
3
4
<h1>タスク一覧</h1>
<% @tasks.each do | task | %>
<%= task.name %>
<% end %>
@tasksには、tasksテーブルの全レコードが代入されています。これをeachメソッドを使って1つ1つ取り出してタスクの名前だけを表示させています。この様に、テーブルから取得したデータをインスタンス変数を使ってビューに渡し展開させることによって、データを見た目に反映させる事が出来ます。
RailsアプリケーションのMVCの流れ
Railsアプリケーションの主なMVCの流れをまとめると、下記の様な図の流れになります。
上記の図を見ると、各要素の関係性は命名規則によって紐づいている事も分かります。
Railsアプリケーションを開発する上で、各要素の関係性をしっかりと把握する事が出来ると、今作成しているものがアプリケーションの中ではどんな役割なのかを理解しやすくなります。
もっと詳しく「Webページが表示される仕組み」から「Railsの処理の流れ」を学びたい人は、こちらの記事を参考にしてください!
MVCのそれぞれの役割を理解しよう!
MVCの流れを理解する事が出来たのでそれぞれの役割を下記の順番で解説していきます。
- Model(モデル)
- View(ビュー)
- Controller(コントローラー)
Model(モデル)の役割
Modelの主な役割は、データベースを管理する事です。コントローラーからの指示に従い必要なデータを取得してコントローラーへ返します。データの取得だけではなく、コントローラーからの命令によっては、データを更新や削除します。
また、ビジネスロジックと呼ばれる一連の流れをプログラムコードとして実装する部分はModelに書きます。
Modelの主な役割はデータベースの管理ですが、データの検証(バリデーション)やテーブルとの関連付けなど細かい処理もModelの役割です。
View(ビュー)の役割
Viewの役割は、最終的な出力の描画を担当することです。静的なページだけではなく、コントローラーから受け取ったデータを表示させることも可能です。
また、フォームなどでユーザーに名前やコメントなど必要な情報を入力させてコントローラーに渡すことによってデータベースに送信することも出来ます。
Controller(コントローラー)の役割
Controllerの役割は、ViewとModelを繋ぐことです。
Controllerでは、データの表示はViewに、ロジックの実行はModelに切り分けます。ロジック部分をModelに書かずにControllerに書く事は出来ますが、その様なコードを書くとファットコントローラーと呼ばれ、コードが管理しづらい状態になります。
ファットコントローラーにしない様に、データベースの管理以外の細かい処理もModelに切り分けてControllerではモデルで実行したメソッドの返り値を受け取るようにしましょう。
▼ データベースについて不安がある方は、基礎から一通り学べる以下の参考書を利用すると良いでしょう。
PCがあれば、データベースの動作と役割が「全部」わかる!
この記事のまとめ
- MVCとはモデル、コントローラー、ビューの頭文字を取った言葉です。
- それぞれ担当するものを分けることで、コードの可読性が上がります。
- MVCの流れを意識しながらrailsの勉強を行うとより理解が深まるでしょう。