ライフサイクルとは、アプリケーションの処理が開始してから終了するまでのプロセスのことです。
Webアプリにおいてはユーザがページにアクセスしてから、そのページを離れるまでの流れを指します(正確にはセッションの開始から終了まで)。
Ruby on Railsではどのような流れで処理が行われているのでしょうか。

ライフサイクルを把握しておくことでRailsの処理の全体像を掴むことができ、理解をぐっと深めることができます。

オンラインでプログラミング学習を始めてみたいなら、米国シリコンバレー発祥の世界最大級のオンライン学習プラットフォーム、Udemyがおすすめです。
こちらの記事で紹介するフレームワーク、Ruby on Railsも学ぶことができます!
よくわかるRuby on Rails入門 オンライン講座

Ruby on Railsのライフサイクル

本記事は、ある程度Ruby on Railsの基礎的な知識がある方を対象としています。
実際にRailsを使用したアプリケーション制作をする前に、処理の全体像を掴んでいただくためにぜひ読んでいただきたい内容となっています。
Railsの理解に自信がない方は、以下の記事を読んでからもう一度こちらの記事に戻ってみてください。

ライフサイクル

ライフサイクルとはもともと、生命が生れてから死ぬまでの過程を環状で表したものです。
そこから派生して、製品などが市場に現れてから衰退するまでの様子を意味するマーケティング用語としても使われるようになりました。

さらにアプリケーションにおいては、そのアクティビティが始まって(アプリケーションが起動して)から終了するまでのことをライフサイクルと呼びます。
アプリケーションは起動時に、そのアプリケーション自身を表すようなコアとなるオブジェクト(アプリケーションクラスのインスタンス)を生成します。
このオブジェクトによって処理が成立しており、これはアプリケーションの終了時に破棄されます。

こういったアプリケーションクラスのオブジェクトの生成から破棄までの過程を、生物の誕生から死までの過程に対応付けた関係のことを、アプリケーションのライフサイクルといいます。

アプリケーションのシステムがどのようなライフサイクルで処理を組み立てているのかを、アーキテクチャといいます。
ソフトウェアアーキテクチャの中には汎用的に用いられている構成がいくつかあり、これらはアーキテクチャパターンと呼ばれています。
Webアプリ開発に用いられている代表的なアーキテクチャパターンのひとつにMVCアーキテクチャがあり、Ruby on Railsもこちらを採用しています。

MVCアーキテクチャ

MVCアーキテクチャでは、Webアプリケーションにおけるライフサイクルを役割ごとに大きく3つに分け、処理を行います。
MVCとは、Model(モデル)・View(ビュー)・Controller(コントローラ)の頭文字です。
それぞれがどのような役割を持つのかを見ていきましょう!

モデルは、アプリケーションにおいて欠かせないデータベースを扱うためのインタフェースです。
データベースに対してクエリを発行したり、処理中で扱いやすい形にデータを加工したりといった役割を持ちます。

ビューは、ユーザに対して表示するページのレンダリングを行います。
コントローラからデータを受け取りHTMLファイル内にその値を埋め込むことでユーザの目に映る部分の生成を行います。

コントローラは、アプリケーション全体を指揮する司令塔です。
処理の流れを制御し、モデルに対してデータの操作を指示したり、ビューに対してデータを渡したりします。

またMVCの頭文字には含まれていませんが、ユーザがアクセスしたURLと呼び出す処理(コントローラのメソッド)を対応付ける役割をする、ルータ(URLディスパッチャ)というものも大事な要素のひとつです。
ルータによって呼び出されるコントローラのメソッドのことをアクションと呼びます。

これらを整理すると、アプリケーション全体の流れは以下のようになります。

処理の流れを文章でも説明します。

  1. ユーザからリクエストされたURLをもとにルータで呼び出す処理を決定する(ルーティング)
  2. コントローラのアクションが呼び出され、メインとなる処理が開始する
  3. アクションの処理中にデータベースのデータを扱う必要があった場合は、モデルを通じてデータベースにアクセスする
  4. ユーザに対して表示したいデータをコントローラからビューに渡す
  5. ビューでHTMLのテンプレートに対して受け取ったデータを埋め込み、最終的なHTMLファイルを生成する(レンダリング)
  6. コントローラからユーザに対して配信したいファイル(HTML、CSS、JavaScript、画像ファイルなど)をレスポンスする

現場を意識した本格的な学習カリキュラムで、本物のスキルを身につけたいならこちら!
困ったときにいつでも相談できるバディ制度でわからないこともすぐに解決できます。
プログラミングスクールといえば【RUNTEQ】

リクエストからレスポンスまでの流れ

ここまでMVCアーキテクチャにおける全体の処理の流れを確認してきましたが、ここからは具体的にどのようにプログラムが実行されているのかを見ていきましょう。

アプリケーションの準備

今回はイベント管理アプリを作りながらライフサイクルをより深く理解していきましょう。
同じ環境で試してみたい方は、以下に従ってコマンドを実行しておいてください。

# 新規プロジェクトの作成
$ rails new event-app
$ cd event-app

scaffoldコマンドでEventモデル周りのファイルを自動生成
$ rails generate scaffold event name:string hold_date:date

# データベースの作成
$ rails db:create

# マイグレーションの実行
$ rails db:migrate

データベースに適当なレコードを追加しておきましょう。

$ rails console

irb(main):001:0> event = Event.new
   (1.1ms)  SELECT sqlite_version(*)
=> #<Event:0x00000155878975c8 id: nil, name: nil, hold_date: nil, created_at: nil, updated_at: nil>

irb(main):002:0> event.name = 'sample event'
=> "sample event"

irb(main):003:0> event.hold_date = Time.parse('20220101')
=> 2022-01-01 00:00:00 +0900

irb(main):004:0> event.save
  TRANSACTION (0.1ms)  begin transaction
  Event Create (44.3ms)  INSERT INTO "events" ("name", "hold_date", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["name", "sample event"], ["hold_date", "2022-01-01"], ["created_at", "2021-11-10 14:46:47.276325"], ["updated_at", "2021-11-10 14:46:47.276325"]]
  TRANSACTION (29.9ms)  commit transaction
=> true

また、以下のコマンドでRailsのアプリケーションサーバを起動しておきましょう。

$ rails server

ここで、http://127.0.0.1:3000/eventsにアクセスしてみると、以下のように表示されます。

ユーザから見れば、URLにアクセスしたらブラウザにWebアプリの画面が表示されただけですが、実際に裏ではどのようにライフサイクルが形成されているのでしょうか?

ルーティング(URLディスパッチャ)

まず最初にルーティングでは、クライアントからのリクエストに応じてどのコントローラのどのアクションを実行するかという紐づけを行います。
このような機能のことを、URLのディスパッチといいます。
ルーティングの対応付けの設定は、config/routes.rbに記述します。

今回はgenerateコマンドを使用したため、routes.rb内に自動的に定義が追加されています。
scaffoldで追加されたルーティングを実際に見てみると、以下のようになっています。

Rails.application.routes.draw do
  resources :events
end

resourcesでルーティングが定義されていますが、これは少し特殊な書き方です。
そのため、受け取ったURLに対してどのような処理が紐づいているのかがわかりにくくなってしまっています。

そこで、アプリケーションで定義されているルーティングの一覧を見てみましょう。
http://127.0.0.1:3000/rails/info/routesにアクセスしてみてください。
以下のようにルーティングの一覧を見ることができるはずです。
ルーティングの一覧は、ターミナル上でrails routesコマンドを実行することでも確認できます。

一番最初に書かれているルーティングが今回アクセスしたURLになっています。
こちらを見ると対応するコントローラはevents、対応するアクションはindex(メソッド)になっていることがわかります。

Helper         Http Verb     Path                  Controller#Action
---------------------------------------------------------------------------
events_path    GET           /events(.:format)     events#index

コントローラの実行

ルーティングで呼び出されているコントローラとアクションがわかったので、その中身を確認してみましょう。

コントローラに関するファイルはapp/controllersディレクトリ内にあります。
generateコマンドで自動生成された、events_controller.rbを見てみましょう。

class EventsController < ApplicationController
  before_action :set_event, only: %i[ show edit update destroy ]

  # GET /events or /events.json
  def index
    @events = Event.all
  end

  # GET /events/1 or /events/1.json
  def show
  end

  # GET /events/new
  def new
    @event = Event.new
  end

  # GET /events/1/edit
  def edit
  end

  # POST /events or /events.json
  def create
    @event = Event.new(event_params)

    respond_to do |format|
      if @event.save
        format.html { redirect_to @event, notice: "Event was successfully created." }
        format.json { render :show, status: :created, location: @event }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @event.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /events/1 or /events/1.json
  def update
    respond_to do |format|
      if @event.update(event_params)
        format.html { redirect_to @event, notice: "Event was successfully updated." }
        format.json { render :show, status: :ok, location: @event }
      else
        format.html { render :edit, status: :unprocessable_entity }
        format.json { render json: @event.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /events/1 or /events/1.json
  def destroy
    @event.destroy
    respond_to do |format|
      format.html { redirect_to events_url, notice: "Event was successfully destroyed." }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_event
      @event = Event.find(params[:id])
    end

    # Only allow a list of trusted parameters through.
    def event_params
      params.require(:event).permit(:name, :hold_date)
    end
end

たくさんのアクション(メソッド)が定義されていますが、ここではindexに注目します。
@つきの変数eventsはビューから参照できる変数、言い換えるとコントローラからビューに渡される変数といえます。
events変数には、Eventモデルからデータを全件取得して代入しています。
たった3行のメソッド(内容は実質1行)の中にRuby on RailsのMVCすべての役割が詰まっています。

  def index
    @events = Event.all
  end

プログラミングでわからないことがあったら、その道のプロに質問するのが一番!
現役で活躍中のエンジニアと繋がって、効率的にWeb開発のスキルを身につけましょう。
プログラミング学習のスキルプラットフォーム【MENTA】

データベースへのアクセス

コントローラ内ではデータベースのレコードを取得したり、レコードの作成や更新や削除を行ったりします。
データベースへのアクセスを担当しているのはモデルで、コントローラはモデルがどのようなデータ処理を行うかの指示を出します。

モデルに関するファイルはapp/modelsにあります。

indexアクションではEventモデルに対してデータを全件取得するように命令をしています。
実際、モデルはデータベースに対して以下のようなSQLのクエリを発行しており、取得した結果をプログラム上で扱いやすいようにオブジェクトとして保持しています。

$ rails console

irb(main):001:0> events = Event.all()
   (1.1ms)  SELECT sqlite_version(*)
  Event Load (0.3ms)  SELECT "events".* FROM "events"
=>
[#<Event:0x000001e25c778270
...

Railsでモデルの役割をしている機能はActive Recordというものです。
基本的なCRUDの書き方は必ず身につけておきましょう!

ビューのレンダリング

コントローラのアクションが実行された後に、ビューでHTMLファイルのレンダリングが行われます。
レンダリングされたファイルはコントローラに渡され、コントローラからクライアントにレスポンスされます。

ビューに関するファイルはapp/viewsにあります。
今回呼び出されたのはapp/views/events/index.html.erbで、中身は以下のようになっています。
基本的には通常のHTMLの書き方と同様ですが、一部Rails特有の記法があり、これらは最終的に通常のHTMLの形式に整えられます。

<p id="notice"><%= notice %></p>

<h1>Events</h1>

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Hold date</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @events.each do |event| %>
      <tr>
        <td><%= event.name %></td>
        <td><%= event.hold_date %></td>
        <td><%= link_to 'Show', event %></td>
        <td><%= link_to 'Edit', edit_event_path(event) %></td>
        <td><%= link_to 'Destroy', event, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Event', new_event_path %>

ビューはhtmlフォーマットだけではなく、APIで使いやすい形式のjsonフォーマットも用意されています。
その場合はhttp://127.0.0.1:3000/events/1.jsonのURLにアクセスすればデータを取得できます。

まとめ

クライアントコンピュータのリクエストに対してRailsがどのようなプロセスで処理を行いレスポンスを生成しているのかを見てきました。
MVCアーキテクチャとしてのそれぞれの役割も明確になり、ライフサイクルの概要がつかめたのではないでしょうか?

改めて処理の流れを確認しておきましょう。

  1. ユーザからリクエストされたURLをもとにルータで呼び出す処理を決定する(ルーティング)
  2. コントローラのアクションが呼び出され、メインとなる処理が開始する
  3. アクションの処理中にデータベースのデータを扱う必要があった場合は、モデルを通じてデータベースにアクセスする
  4. ユーザに対して表示したいデータをコントローラからビューに渡す
  5. ビューでHTMLのテンプレートに対して受け取ったデータを埋め込み、最終的なHTMLファイルを生成する(レンダリング)
  6. コントローラからユーザに対して配信したいファイル(HTML、CSS、JavaScript、画像ファイルなど)をレスポンスする

ひとりではなかなかプログラミングの学習が続かない、未経験だから不安が多い、という方はプログラミングスクールを利用してみるのも有効です。
本物のエンジニアに学ぶことで、時間がない方でも最短でスキルを身につけることができます。
現役エンジニアのパーソナルメンターからマンツーマンで学べる

お悩みの方は、まずは無料キャリアカウンセリングにお申込みください。

関連記事

この記事のタグ