コントローラーとビューの関係【Ruby on Rails超入門】処理の流れを初心者にも分かりやすく解説

2019年1月1日火曜日

Ruby on Rails

Ruby on Railsのコントローラーとビュー

こんにちは、財前航介です。

本日は、Ruby on Railsにおける、コントローラーとビューの関係について学んでいきましょう。

単純に具体例を用いてコントローラーとビューの関係を説明するだけでなく、Ruby on Railsがリクエストを受け付けてからの処理の流れも分かるように説明していきたいと思います。


コントローラーとビューの関係【Ruby on Rails超入門】

コントローラーとビュー

MVCモデル


Ruby on Railsの使用経験がある方も、これから触ってみる方も、Web技術に携わったことがあれば、コントローラービューという言葉を聞いたことがある方も多いのではないでしょうか。

これらの言葉はRuby on Rails特有の用語ではなく、「MVCアーキテクチャー」という、Webアプリケーションの開発全般の、設計思想を表している言葉です。

具体的には、Webサーバー側で、以下のような処理の切り分けを行っているような構成を、MVCアーキテクチャーと言います。

モデル ビュー コントローラー

こちらの記事では上記の図にもあるように、ユーザーからのリクエストに応じて、コントローラーがビューの内容を送り返すまでの流れを見ていきましょう。

(モデルによるデータベースへの接続は、簡単のためこの記事では触れないこととします。)


具体例


漠然としたMVCアーキテクチャーの説明よりも、具体例を見てみた方が分かりやすいと思います。

ここでは、ブラウザに入力されたURLに応じて、以下のような2つの画面を表示する例を見てみましょう。

※各画面に表示されている内容は、後ほど順を追って説明していくので、今は画面の内容を詳しく読まなくても大丈夫です。


画面1
アクション1に対応するビュー

画面2
アクション2に対応するビュー


上記のような2つの画面を出し分けるような構成の、非常に簡単なWebアプリケーションの例を考えます。

どのようにして上記のような画面が表示されるのか、順を追って見ていきましょう。


編集を行うファイル一覧


上記の2つの画面を作成するためにここで確認するファイルは、以下のものです。

(パス)
ファイル名
役割
(/config/)
routes.rb
ブラウザからのリクエストに応じて、コントローラーアクションを呼び出す。
(/app/controllers/)
con1_controller.rb
【コントローラー】 呼び出されたアクションに応じて、ブラウザ側にビューを送り返す。
(/app/views/con1/)
act1.html.erb
【ビュー】 act1というアクションが呼び出された時に用いられるビュー
(/app/views/con1/)
act2.html.erb
【ビュー】 act2というアクションが呼び出された時に用いられるビュー

処理の流れ


上記のファイルによって行われる処理の流れを図で表すと、以下のようになります。

Ruby on Railsの処理の流れ


  • Webブラウザからのリクエストを、routes.rbが受け付ける。
  • 受け取ったリクエストに応じて、routes.rbが、適切なコントローラーアクションを呼び出す。
  • コントローラーは、呼び出されたアクションに対応するビューを加工し、表示する。


各ファイルの内容


上記のような処理の流れを実現するための、各ファイルの内容を見ていきましょう。


●routes.rb:
#routes.rb

Rails.application.routes.draw do
  get 'con1/act1'
  get 'con1/act2'
end

routes.rbには、リクエストに応じて呼び出されるコントローラーのアクションが記載されています。

ブラウザから直接URLを入力するようなタイプのリクエストには「get」という記載を行います。
これは、getという名前のHTTPメソッドを用いて、リクエストが送信されるためなのですが、ここではあまり気にしなくても良いでしょう。


この例では「con1/act1」というリクエストを受け取ると、con1コントローラーの中のact1アクションを呼び出します。

同様に、「con1/act2」というリクエストを受け取ると、con1コントローラーの中のact2アクションを呼び出します。


●cont1コントローラー
#cont1 コントローラー

class Con1Controller < ApplicationController

  #act1 アクション
  def act1
    #インスタンス変数1
    @con1_instance_val1 = "1つ目のインスタンス変数です。"

    #インスタンス変数2
    @con1_instance_val2 = Date.today
  end

  #act2 アクション
  def act2
    #インスタンス変数3
    @con1_instance_val3 = "3つ目のインスタンス変数です。"
  end

end

上記のように一つのコントローラーは、複数のアクションを含みます。

アクションとは、コントローラークラスのメソッドのことなのですが、ここでは「アクション」「メソッド」という呼び方の違いは、あまり気にしなくて良いでしょう。

気になる方は、以下の記事をご参照ください。
アクションとは【Ruby on Rails超入門】>>


各アクションの中では、インスタンス変数に値を代入しています。
以下のような記載がそれに当たります:

@con1_instance_val1 = "1つ目のインスタンス変数です。"

先頭に@(アットマーク)を付けると、その変数はインスタンス変数とみなされます。

インスタンス変数というと、オブジェクト指向プログラミングを学習するときに頻繁に耳にする用語ですが、
Ruby on Railsのコントローラーにおけるインスタンス変数は、

「ビューと値が共有できる変数」

という風に覚えて頂けると良いと思います。


ただ、上記の記述では、アクションを跨いでで共有されるようなことはないので、そこも後ほど確認していきましょう。


●act1アクションに対応するビュー
<!-- act1.html.erb -->

<h1>act1というアクションに対応するビュー</h1><br />
<b>views/con1</b>フォルダの中にある、<b>act1.html.erb</b>です。<br />
<br />
試しにcon1コントローラーのインスタンス変数を呼び出してみましょう。<br />
<br />
インスタンス変数1<br />
@con1_instance_val1: <b><%= @con1_instance_val1 %></b><br />
<br />
インスタンス変数2<br />
@con1_instance_val2: <b><%= @con1_instance_val2 %></b><br />
<br />
インスタンス変数3<br />
@con1_instance_val3: <b><%= @con1_instance_val3 %></b>

コントローラー内のact1というアクションが呼び出された時にブラウザーに送り返されるHTMLファイルのひな形が、上記の赤字のファイルです。

基本的にはHTMLが記載してあるだけなのですが、よく見ると特殊な書き方をしている部分があります。

下記のような記号で囲まれた部分がありますね。
<%=  %>

これは、HTML内でRubyのソースコードを呼び出す際に用いられる記号です。

ここにコントローラーで定義したインスタンス変数を書き込むと、その値がHTML上に展開されて、ユーザーに送信されるのです。

展開された結果を確認する前に、act2アクションに対応するビューのファイルも見ておきましょう。


●act2アクションに対応するビュー
<!-- act2.html.erb -->

<h1>act2というアクションに対応するビュー</h1><br />
<b>views/con1</b>フォルダの中にある、<b>act2.html.erb</b>です。<br /><br />

試しにcon1コントローラーのインスタンス変数を呼び出してみましょう。<br /><br />

インスタンス変数1<br />
@con1_instance_val1: <b><%= @con1_instance_val1 %></b><br /><br />

インスタンス変数2<br />
@con1_instance_val2: <b><%= @con1_instance_val2 %></b><br /><br />

インスタンス変数3<br />
@con1_instance_val3: <b><%= @con1_instance_val3 %></b>

上記の青字のファイルが、act2というアクションが呼び出された時に表示されるビューのファイルです。

内容はほとんどact1のビューファイルと一緒ですね。


act1act2に対応するビューファイルのファイル名は、それぞれ以下のようなものでした。

  • act1.html.erb
  • act2.html.erb

実はこのファイル名は自由に決めて良いものではなく、コントローラー側と整合を取った命名を行う必要があります。

以下のような命名を行う必要があるのです。

[アクション名].html.erb

また、このファイルを格納するフォルダ階層は、「/app/views/con1/」のように、コントローラー名と同じ名前のフォルダの中に配置する必要があります。

Ruby on Railsの理念の一つに、
「設定より規約」
という考え方があります。

これは、Ruby on Rails側で定められた規約に従うことによって、いちいち設定を行う手間を減らし、プログラマーが開発をしやすいようにするための考え方です。

このビューの命名ルールのように、Ruby on Railsによって定められた規約に従っておけば、コントローラーのアクションとビュー側との紐づけの設定などをしなくても済むということは、Ruby on Railsというフレームワークを用いる上での大きなメリットです。

名前だけ付けておけば自動で紐づくのですから、設定の手間は減りますね。

Ruby on Railsを導入することによるメリットについて詳しく知りたい方は、以下の記事もご参照ください。
Ruby on Railsのメリット・デメリット【初心者にもわかりやすく解説】>>

実行結果を再確認


上記のようなソースコードを実行した結果を、もう一度見てみましょう。


con1/act1というリクエストを送信した場合:
act1というアクションに対応するビュー

上記のように、act1アクションに対応している画面では、インスタンス変数1インスタンス変数2のみに値が入っており、インスタンス変数3の中身は空っぽです。


con1/act2というリクエストを送信した場合: 
act2というアクションに対応するビュー

一方で、act2アクションに対応する画面では、インスタンス変数1インスタンス変数2の中身は空っぽで、インスタンス変数3のみに値が格納されています。

つまり、この例のようなコントローラーの記述では、アクションを跨いでインスタンス変数の代入は行われていないことが分かります。

呼び出されたアクションの中で代入した変数以外は、代入が行われていなくて当然といえば当然ですね。



まとめ:
Ruby on Railsのコントローラーのアクションと、ビューが対応している

コントローラーとビュー

如何でしたでしょうか?
Ruby on RailsのWebサーバーが、リクエストを受け付けてからの処理の流れの大枠を理解して頂けたでしょうか。

タイトルにもあるコントローラーとビューの関係ですが、以下のようなことが言えます。

  • リクエストに応じて、routes.rbが適切なコントローラーアクションを呼び出す

  • コントローラーアクションには、Rubyで処理が記載されている

  • コントローラーアクションと、ビューのファイルが1対1で対応している

  • ビューには、ブラウザーに送信するためのHTMLのひな形が記載されている

  • コントローラーで設定されたインスタンス変数がビュー内に展開されて、HTMLになる

  • インスタンス変数には@(アットマーク)を付ける

推薦図書:
基礎 Ruby on Rails


Ruby on Railsについてより詳しく学びたい方には、以下の書籍がオススメです。


私自身が最初にRuby on Railsを学んだ時に用いた書籍の、最新版です。
その後も数冊Ruby on Railsの本を読みましたが、この書籍が一番わかりやすいと感じました。

また、WindowsとMacの両方のコマンドを書いてくれているので、どちらのPCをお使いの方でも、環境構築から、本格的なWebアプリケーションの構築まで、順を追って学んでいくことができます。

Ruby on Railsを用いたWebアプリケーションの開発に携わる方であれば、ぜひお手元に1冊持っておくことをお勧め致します。