【復習】Ruby on Rails入門 ~ミニブログを作りながら学ぶWebアプリケーション制作 第2回~
無料動画のオンライン学習サイトのスクーで鳥井 雪(@yotii23)先生が教えてくださる
RoR入門第2回を復習します。
Ruby on Rails入門 ~ミニブログを作りながら学ぶWebアプリケーション制作 第2回~ 鳥井 雪 先生 - 無料動画学習|schoo(スクー)
ゴール
- リクエストからレスポンスまでの、Rails内部での処理の流れを理解する。
- View(表示)のカスタマイズができるようになる。
リクエストからレスポンスまでのRailsの処理の流れ
1.routes.rbで処理を分岐する。
URL+HTTPメソッドでどの処理を実行するかは ./config/routes.rb
で定義する。
前回scaffoldで生成したentriesは以下のように定義されている。
Rails.application.routes.draw do resources :entries
リクエスト(URL+HTTPメソッド)を受けたRailsは routes.rb
でどの処理を
呼び出すかを、決定し、その"処理"を実行してレスポンスを返す。
※同じURLでもHTTPメソッドが違っていれば異なる処理を実行することもある。
処理を構成する三要素:MVC
"処理"は3つの要素に分かれていて、それをMVCと呼ぶ。
- M:Model(モデル)
- V:View(ビュー)
- C:Controller(コントローラ)
2.MVCでレスポンスをつくる
- routes.rbからどのControllerのどの処理を実行するか決定する。*
- Controllerを呼び出す。*
- ControllerがModelを呼び出す
- Modelがデータを用意し、Controllerに返す
- ControllerがデータをViewに渡す
- Viewがレスポンスを用意する
※処理の流れの理解は大事
MVCの基本
RailsのMVCディレクトリ構造
./my_app/app/
の下にmodels,controllers,viewsが配置されている。
my_app ├── app │ ├── assets │ ├── controllers * │ ├── helpers │ ├── mailers │ ├── models * │ └── views *
Controllerの主な役割
routes.rb
から一番最初に呼ばれる- Modelを呼び出してデータを揃える(揃えさせる)
- 揃えた(Modelから受け取った)データをViewに渡す
前回、scaffold
で生成したentryのコントローラはentries_controller.rb
class EntriesController < ApplicationController before_action :set_entry, only: [:show, :edit, :update, :destroy] # GET /entries # GET /entries.json def index @entries = Entry.all end ~略~
- URLで
/entries
を指定してアクセスした場合、routes.rb
はdef index
を呼び出す。 - #で始まるコメントに対応するURLが記載されている。(コマンドで作成した場合)
Entry.all
は一覧画面用にモデルから全てのデータを取得する処理。- @entriesはインスタンス変数で、インスタンス変数の値はViewに渡すことができる。
def
からend
までの間にViewを呼び出す処理がないが、railsが対応するViewを呼び出す。
HTTPメソッドとControllerの対応付けは以下が参考になります。
Modelの主な役割
- データのやり取りを担当する
- ActiveRecode::Baseに基本の機能が用意されている
- クラスの名前からテーブル名を推測する
前回、scaffold
で生成したentryのモデルはentry.rb
class Entry < ActiveRecord::Base end
- クラスをみると空だが、Railsが用意している
ActiveRecode::Base
を継承している。 - モデルに対応するテーブル名は命名規則(テーブル名;モデル名の複数形)から推論している。
- ここにはモデル固有の処理(文字数制限をしたり他のデータとの関係性などをつけたり)を書いていく。
Viewの主な役割
- 渡されたデータに基づいてHTML(など)を組み立てる
- 「画面」ごとに対応する1ファイルがある
前回、scaffold
で生成したentryのビューは/views/entries
配下の複数ファイル
サンプルは index.html.erb
<p id="notice"><%= notice %></p> <h1>Listing Entries</h1> <table> <thead> <tr> <th>Name</th> <th>Body</th> <th colspan="3"></th> </tr> </thead> <tbody> <% @entries.each do |entry| %> <tr> <td><%= entry.name %></td> <td><%= entry.body %></td> <td><%= link_to 'Show', entry %></td> <td><%= link_to 'Edit', edit_entry_path(entry) %></td> <td><%= link_to 'Destroy', entry, method: :delete, data: { confirm: 'Are you sure?' } %></td> </tr> <% end %> </tbody> </table> <br> <%= link_to 'New Entry', new_entry_path %>
<% @entries.each do |entry| %>
の@entries
はControllerに登場したインスタンス変数。<% code %>
は中に記載したRubyコードを実行する。(実行のみ)<%= code %>
は中に記載したRubyコードを実行し、その実行結果を埋め込む。<td><%= entry.name %></td>
はentry.name
を実行し、その実行結果がもしz_a_ki3
であれば
<td>z_a_ki3</td>
となる。
ちなみに link_to
は良い感じにリンクを生成してくれるヘルパーと呼ばれるものなんですが、詳細は別途・・・
MVCのメリット
MVCと3つに役割を分担することで、開発しやすくメンテナンスしやすいアプリケーションになる。
MVCはRailsでもJava、ASP.NETなどでも当たり前になっているデザインパターンなので、
MVC何それおいしいの?状態にならないように基本的なことは押さえておいた方が良いと思います。
ただ、MVCは"こう実装するのがジャスティス!"なものが無いのでここは経験を積みましょう。
HTTPメソッドの種類
HTTPメソッド | 処理内容 |
---|---|
GET | データを取得する |
POST | 作成 |
PUT(PATCH) | 更新 |
DELETE | 削除 |
このなかで更新はPUTとPATCHで多重定義されています。
授業の中では仕様が揺れていると言うことでしたが、Rails4で更新はPATCHとされたようです。
なので、新しいRailsを使うのであれば"更新はPATCH"と考えても良いかもしれません。
また、PUTとPATCHの違いについては以下のページに詳細があります。
次期RailsがPATCHメソッドを採用 - ぶろぐ。@はてな
CRUDとHTTPメソッドの対応
CRUD | HTTPメソッド |
---|---|
CREATE | POST |
READ | GET |
UPDATE | PUT(PATCH) |
DELETE | DELETE |
Viewをカスタマイズしよう!
アンケート:HTMLとCSSの関係が説明できますか?
- HTMLは文章を構造化する為の言語
- CSSはHTMLなどの構造に対する修飾の定義
Viewの役割
- レスポンスの最終的な形を整形する
- HTML+Rubyのプログラム+RailsでHTMLを便利に書くヘルパー
- <% %>で囲まれた部分はRubyのプログラムを書ける
- <%= %>で囲まれた部分はRubyのプログラムを使って書き出される内容がかける
app/views/entries.index.html.erbを編集する
まずは表示を日本語に変更します。
編集前
編集前 <h1>Listing Entries</h1> 編集後 <h1>投稿一覧</h1>
一覧画面以外のタイトルは当然、影響を受けていません。
app/views/layouts/application.index.html.erbを編集する
編集前 <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> 編集後 <link rel="stylesheet" href="//railsgirls.com/assets/bootstrap.css" /> <link rel="stylesheet" href="//railsgirls.com/assets/bootstrap-theme.css" /> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
変更前 <%= yield %> 変更後 <div class="container"> <%= yield %> </div>
※これはRails Girlsのサイトで配備されてるcssファイルを拝借してる感じなので、実際の自分のアプリを使う場合は、
自分でダウンロードしたファイルを使うか、Bootstrap CDNを使わないとダメですね。
編集前 <link rel="stylesheet" href="//railsgirls.com/assets/bootstrap.css" /> <link rel="stylesheet" href="//railsgirls.com/assets/bootstrap-theme.css" /> 編集後 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" /> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css" />
これで一覧画面、詳細画面、作成画面等を見ると全ての画面で追加したスタイルシートが適用されてます。
ここで登場している <%= yield %>
の裏にある処理がとっても気になるんですが、とりあえず、
関連しそうなリンクを張り逃げして、再復習の時にまた追っていきたいと思います。
yield を理解できるまで寝ないスレッド · Issue #336 · yochiyochirb/meetups · GitHub
レイアウトと個別のview
- headerやfooterなどの共有部分:
application.index.html.erb
- 個別のページの内容:
index.html.erb
等
app/views/entries/_form.html.erbを編集する
変更前 <%= f.label :name %><br> 変更後 <%= f.label :name,"名前" %><br>
変更前 <%= f.label :body %><br> 変更後 <%= f.label :body,"本文" %><br>
今回、修正した f.label
は次のような構文になっていて、ラベル配下のコンテンツを追加しています。
f.label(プロパティ名 [, ラベル配下のコンテンツ] [, オプション])
個別のviewと共通のview(パーシャル)
/entries/new
と entries/1/edit
の画面を見てみると非常に似た構造になっています。
ここで views/entries
配下の new.html.erb
を見てみると、
new.html.erb <h1>New Entry</h1> <%= render 'form' %> <%= link_to 'Back', entries_path %>
<%= render 'form' %>
と <%= link_to 〜 %>
しかありません。
次に edit.html.erb
を見てみると、
edit.html.erb <h1>Editing Entry</h1> <%= render 'form' %> <%= link_to 'Show', @entry %> | <%= link_to 'Back', entries_path %>
同じく <%= render 'form' %>
と <%= link_to 〜 %>
しかありません。
この中で <%= render 'form' %>
が、先ほど編集した _form.html.erb
に対応しています。
個別のViewの中で共通している部分をパーシャルという仕組みでまとめる事ができます。
パーシャルのファイル名は""(アンダーバー)からはじめ、render
で指定するときは""を外す。
次回以降の内容
宿題
- 自分で個別のviewファイルとレイアウトのファイルを書き換えてみて、その変更を見てみましょう
- 全ページに共通のフッターをつけてみましょう
application.html.erb
を修正
変更前 <%= yield %> 変更後 <%= yield %> <footer>© Copyright 2015, @z_a_ki3.</footer>
単純に足しただけ・・・
- /entries/ ページの "Name" と "Body" を日本語に書き換えてみましょう。
index.html.erb
を修正
変更前 <th>Name</th> <th>Body</th> 変更後 <th>名前</th> <th>本文</th>
単純に変えただけ・・・
質疑応答
オススメのサイト