【Rails】MVCフレームワークについて、初心者の為に世界で一番丁寧に解説!

Rails

MVCフレームワークとは?

MVCフレームワークは、MVCというデザインパターンを取り入れたフレームワークのことです。

つまり、MVCは機能のことではなく、アプリケーションを作成する時にコードを綺麗に保って管理するための考え方のことです。

また、Ruby on Railsは、プログラミング言語であるRubyで書かれたWebアプリケーションフレームワークですが、MVCというデザインパターンが取り入れられたMVCフレームワークでもあります。

Ruby on RailsのMVCの流れを理解しよう
リンクをコピーしました

Railsアプリケーションは、ルーティング(Routes)→コントローラー(Controller)→モデル(Model)→ビュー(View)の順番で処理が実行されます。

そして、クライアントがリクエストしてからレスポンスを受け取るまでの流れは、下記の図の流れになります。

クライアントがリクエストしてからレスポンスを受け取るまでの流れ

ピカわかのサイトを検索してから、トップページを表示するまでに内部ではいくつもの処理が実行されているのです。それでは、それぞれの流れを詳しく解説していきます。


リクエストからコントローラーまでの流れ
リンクをコピーしました

下記の図の1〜3までがリクエストからコントローラーの流れになります。

今回は、RailsでMVCを理解しやすくする為に、クライアントがリクエストするURLを開発環境でタスク一覧ページを表示させる「localhost:3000/tasks」に変更しています。

リクエストからコントローラーまでの流れ

クライアントからのリクエスト(❶)はURL(localhost:3000/tasks)としてアプリケーションのルーティング(❷)に届きます。

ルーティングは、送信されたリクエストに対し、どのコントローラーのアクションを動かすのかを設定する場所です。ルーティングのファイル(config/routes.rb)を確認すると、下記のように設定されています。

config/routes.rb
1
2
# "tasks#index"は、"コントローラー名#アクション名"のこと
get "tasks" => "tasks#index"

このルーティングファイルで設定されている内容は、下記の3つあります。

  1. get "tasks"の「get」は、HTTPリクエストのGETメソッドを表します。(HTTPメソッドについては、下記の表を参考にして下さい。)

  2. 「get "tasks"」は、HTTPメソッドのGETで送信される「localhost:3000/tasks」のURLの事です。

  3. 「"tasks#index"」は、tasksコントローラーのindexアクションを使うことを設定しています。

つまり、「GETで送信されたlocalhost:3000/tasks」に対して「tasksコントローラーのindexアクション」が動くという事をroutes.rbで設定しています。

HTTPリクエスト 説明
GET リソースの取得 サイトを表示
POST リソースの作成など 記事の投稿


図をもう一度確認するとルーティング(❷)の次は、コントローラー(❸)が動きます。

リクエストからコントローラーまでの流れ

ルーティングでtasksコントローラーのindexアクションが動くように設定したので、tasksコントローラー(controller/tasks_controller.rb)の中身を確認していきます。

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メソッドを徹底解説!を参考にして下さい。

controller/tasks_controller.rb
1
2
3
4
5
6
class TasksController < ApplicationController
  def index
    # Taskモデルを通してデータベースからデータを取得させる
    @tasks = Task.all
  end
end

しかし、Taskモデルが定義されているtask.rbファイルを確認すると、メソッドは一切定義されていません。

model/task.rb
1
2
class Task < ActiveRecord::Base
end

これは、TaskクラスがActiveRecord::Baseクラスを継承しているからです。現段階では、ActiveRecord::Baseクラスを継承しているからデータベースとやりとり出来る便利なメソッドが使えているという認識で大丈夫です。


indexアクション内で、「Taskモデルを通し、tasksテーブルに保存してある全データを取得する」という流れは、下記の通りです。

tasksテーブルに保存してある全データを取得する流れ

コントローラーからビューまでの流れ
リンクをコピーしました

下記の図の6,7がコントローラーとビューの流れになります。

コントローラー(❼)は、モデル(❹)を通してテーブル(❺)から取得したデータを持っています。これをビュー(❼)に渡すことによって、リクエストされたデータを表示する事が出来ます。

コントローラーからビューまでの流れ

では、テーブルから取得したデータをビューに渡すにはどうすれば良いのでしょうか。もう一度コントローラーファイル(controller/tasks_controller.rb)を確認してみましょう。

indexアクション内では、取得したデータを@tasksに代入しています。「@」がついた変数に値を代入すると、ビューファイルに渡す事が出来ます。(@がつく変数はインスタンス変数と呼びます。)

そして、@tasksをビューファイルで展開する事でデータを表示する事が出来ます。

controller/tasks_controller.rb
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」が呼び出されます。早速ファイルの中身を確認していきましょう。

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アプリケーションの主なMVCの流れ

上記の図を見ると、各要素の関係性は命名規則によって紐づいている事も分かります。

Railsアプリケーションを開発する上で、各要素の関係性をしっかりと把握する事が出来ると、今作成しているものがアプリケーションの中ではどんな役割なのかを理解しやすくなります。

RailsアプリケーションにおけるMVCの流れを整理する事が出来たので次は役割について解説していきます。

MVCのそれぞれの役割を理解しよう!
リンクをコピーしました

MVCの流れを理解する事が出来たのでそれぞれの役割を下記の順番で解説していきます。

  1. Model(モデル)
  2. View(ビュー)
  3. Controller(コントローラー)

Model(モデル)の役割
リンクをコピーしました

Modelの主な役割は、データベースを管理する事です。コントローラーからの指示に従い必要なデータを取得してコントローラーへ返します。データの取得だけではなく、コントローラーからの命令によっては、データを更新や削除します。

また、ビジネスロジックと呼ばれる一連の流れをプログラムコードとして実装する部分はModelに書きます。

Modelの主な役割はデータベースの管理ですが、データの検証(バリデーション)やテーブルとの関連付けなど細かい処理もModelの役割です。

View(ビュー)の役割
リンクをコピーしました

Viewの役割は、最終的な出力の描画を担当することです。静的なページだけではなく、コントローラーから受け取ったデータを表示させることも可能です。

また、フォームなどでユーザーに名前やコメントなど必要な情報を入力させてコントローラーに渡すことによってデータベースに送信することも出来ます。

Controller(コントローラー)の役割
リンクをコピーしました

Controllerの役割は、ViewとModelを繋ぐことです。

Controllerでは、データの表示はViewに、ロジックの実行はModelに切り分けます。ロジック部分をModelに書かずにControllerに書く事は出来ますが、その様なコードを書くとファットコントローラーと呼ばれ、コードが管理しづらい状態になります。

ファットコントローラーにしない様に、データベースの管理以外の細かい処理もModelに切り分けてControllerではモデルで実行したメソッドの返り値を受け取るようにしましょう。

まとめ

  • MVCとはモデル、コントローラー、ビューの頭文字を取った言葉です。
  • それぞれ担当するものを分けることで、コードの可読性が上がります。
  • MVCの流れを意識しながらrailsの勉強を行うとより理解が深まるでしょう。