#MVCとは
Railsを使用する際にMVCというものが出てくる。これは何のことだろうか?それぞれがどこに適用されているのだろうか?という点を今回は追っていく。ちなみにバージョンはRails 4.0.5で説明させていただく。
MVCはModel View Controlの頭文字をとったもの。それぞれ以下のように役割分担している。
- Model:データベースとのやり取り
- View:ユーザーの見える部分を管理する
- Control:ユーザーからのリクエストを受け取り、モデルとビューに役割分担をする
それぞれの役割がわかったところで、実際にどのように動いているのか確認していく。
##scaffoldでMVCを自動生成
確認にあたり、railsの機能を使用してMVCをあらかじめ自動生成してもらう。その生成してくれるコマンドがscaffoldである。
rails generate scaffold Task title:string detail:string
と実行すると自動生成してくれた。今回はTask管理アプリという想定で、アプリ名をTask、データとして、タスク名(title:string) 内容(detail:string)を保持できるようにした。
#ルーティング
ユーザーがサイトに何かしらのリクエストを送ると、まずはルーティングと呼ばれる部分が対応する。ルーティングでは、リクエストに対して適切なコントローラーへ処理を促す。
ルーティングはconfig/routes.rb
に保存されている。以下のコードを追加すると、taskページへのアクセスが要求された場合、コントローラーへ処理を移すことが出来るようになる。複数形なのはミスではなく仕様である。
DemoApp::Application.routes.draw do
resources :tasks
end
#コントローラー
コントローラーは/app/controllers/tasks_controller.rb
に記述されている。
ここでは、モデルとビューに対してどのような処理が必要であるか記述してある。
lass TasksController < ApplicationController
before_action :set_task, only: [:show, :edit, :update, :destroy]
# GET /tasks
# GET /tasks.json
def index
@tasks = Task.all
end
# GET /tasks/1
# GET /tasks/1.json
def show
end
# GET /tasks/new
def new
@task = Task.new
end
# GET /tasks/1/edit
def edit
end
# POST /tasks
# POST /tasks.json
def create
@task = Task.new(task_params)
respond_to do |format|
if @task.save
format.html { redirect_to @task, notice: 'Task was successfully created.' }
format.json { render action: 'show', status: :created, location: @task }
else
format.html { render action: 'new' }
format.json { render json: @task.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /tasks/1
# PATCH/PUT /tasks/1.json
def update
respond_to do |format|
if @task.update(task_params)
format.html { redirect_to @task, notice: 'Task was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @task.errors, status: :unprocessable_entity }
end
end
end
# DELETE /tasks/1
# DELETE /tasks/1.json
def destroy
@task.destroy
respond_to do |format|
format.html { redirect_to tasks_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_task
@task = Task.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def task_params
params.require(:task).permit(:title, :detaile)
end
end
ユーザーからのリクエストに対し、適切な処理が行われるように指定している。
#モデル
モデルは/app/models/task.rb
に保存されている。中身を見てみよう。
class Task < ActiveRecord::Base
end
これだけである。ActiveRecordを継承し、コントローラーからの処理に応える。
#ビュー
ビューは/app/views/tasks/index.html.erb
に保存されている。
<h1>Listing tasks</h1>
<table>
<thead>
<tr>
<th>Title</th>
<th>Detaile</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<% @tasks.each do |task| %>
<tr>
<td><%= task.title %></td>
<td><%= task.detaile %></td>
<td><%= link_to 'Show', task %></td>
<td><%= link_to 'Edit', edit_task_path(task) %></td>
<td><%= link_to 'Destroy', task, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Task', new_task_path %>
見覚えのある記述で少し安心する。要するにHTML文章をrailsで作成してくれるということだ。
#まとめ
正直この記事を書いていてもどのコードがどのような処理をしているのかわからなかった。しかし、MVCの大まかな流れをつかむことはできた。
- ルーティングでコントローラーを指定
- コントローラーでモデルに必要なデータを要求
- モデルからのデータを基にビューを生成
- ユーザーに返す
今後コードを書いていく際に、自分がいまどこの処理を作り上げているのか把握することが大切であると思う。迷ったときには、このまとめを思い出すように心がけたい。
#参考
RailsにおけるMVC(モデル/ビュー/コントローラ)
Ruby on Railsの基本中の基本 MVC + ルーターについて