9. コントローラ¶
9.1. コントローラを作る¶
学部の表示をするコントローラを作ってみる。
rails generate scaffold
がモデル・ビューと一緒に作ってくれるコントローラには、既に表示・編集・追加などの操作が入っている。rails generate controller
は、必要なデータ操作を指定してコントローラを作る。
学部のデータは変更する必要がないので(学部の新設や廃止をするなら話は別だが)、学部の情報を表示する show
という操作だけを作ることにする。
% rails generate controller faculties show
faculties
がコントローラの名前。たまたまモデルと同じ名前(複数形)にしたが、モデルとは関係ない名前でもよい。show
が操作の名前。操作が複数あるときは空白で区切って並べて書く。
これで app/controllers/faculties_controller.rb
というファイルが出来て、 FacultiesController
というクラスに show
というメソッドが用意される。ただし中身は空。
それだけでなく、対応するビューのERBファイル app/views/faculties/show.html.erb
も出来る。
9.2. Railsの処理の流れ大図解¶
コントローラが要求を受け付け、モデルとビューの間に立って処理を進める。要するに、モデルにもビューにも入らないところは全部コントローラに押し付けられる。
ルーティング
HTTPリクエストに対して、どのコントローラのどのメソッドが呼び出されるかという対応関係をルーティングと言う。
上の例だと、ブラウザで http://localhost:3000/faculties/show にアクセスすると、
faculties
コントローラのshow
メソッドが呼び出される。レンダリング
コントローラがビューを使ってレスポンスを作り出すことをレンダリングと言う。コントローラのメソッドの中で特に指定しなければ、コントローラ名とメソッド名から決まるERBファイルが自動的に使われる。
上の例だと、
faculties
コントローラのshow
メソッドには何も書いていないので、 http://localhost:3000/faculties/show にアクセスすると、app/views/faculties/show.html.erb
を使ってレンダリングする。
9.3. コントローラの中身を書く¶
学部ごとに、学部名と学生リストを表示するようにしよう。
コントローラはリクエストを解析してモデルから必要なデータを検索し、それをインスタンス変数に記憶する。
ビューでは、そのインスタンス変数を使って表示を行う。
今は、ちょっと学部の指定は置いといて、常に総合政策学部のデータを取ってくることにする。 app/controllers/faculties_controller.rb
は次のように書く。
class FacultiesController < ApplicationController
def show
@faculty = Faculty.find(1)
end
end
これを表示するためのビュー app/views/faculties/show.html.erb
は次のように書く。
<h1>Faculties#show</h1>
<p><b><%= @faculty.name %></b></p>
9.4. パラメータの指定¶
このままでは環境情報学部が表示できないので、リクエストのURLによって学部を指定するようにしよう。
URLのクエリ文字列(最後に
?hoge=xxx
の形で付いているやつ)で指定された名前と値は、Rubyのハッシュに変換され、params
という変数に格納される。
例えば http://localhost:3000/faculties/show?id=2 でアクセスすると、 show
メソッドの中では params[:id]
の値が2になる。
app/controllers/faculties_controller.rb
は次のように書き直す。
class FacultiesController < ApplicationController
def show
@faculty = Faculty.find(params[:id])
end
end
課題15
学部の表示ページで、その学部に属する学生の番号と名前を表示するようにせよ。
コントローラで学生の配列を
@students
という変数に記憶する。ビューでは
<% @students.each do |s| %> ... <% end %>
の形で各学生のデータを順次表示する。
提出は、 app/controllers/faculties_controller.rb
と app/views/faculties/show.html.erb
をアップロード。
【解答例】
9.5. ルーティングの指定¶
ブラウザからのリクエストをどのコントローラのどのメソッドが引き受けるかは config/routes.rb
で指定する。
基本的には、各行にHTTPリクエストのメソッド(HTTP Verb)とURLのパターンが書いてある。
上から順に見ていって最初にマッチしたところの指示に従う。
9.5.1. 個別のルーティング¶
学部のコントローラーは rails generate controller
で作ったので、 config/routes.rb
には次の行が自動的に追加されている。
get 'faculties/show'
GETリクエストで http://localhost:3000/faculties/show というURLの時にマッチする。
本当は、この後に呼び出すべきコントローラとメソッドの指定を書くが、何も書かないとURLから勝手に判断する。この場合は
FacultiesController
のshow
メソッドが呼ばれる。
9.5.2. パラメータを含むルーティング¶
このルーティングでは、「どの学部か」という指定はURLの最後にクエリ文字列で ?id=2
とか書く必要がある。
クエリ文字列は、長くなってうざい。
パス名の一部に直接パラメータを書くことができる。例えば、2番めの学部の情報を表示するには http://localhost:3000/faculties/2 と書ける。
get 'faculties/:id', to: 'faculties#show'
ルーティングの指定で、URLの中に
:
(コロン)で始まる名前を書くと、その部分がパラメータになる。:id
に対応する部分がparams[:id]
に格納されてメソッドに渡される。
URLが「コントローラ名/メソッド名」という形ではないので、コントローラ名とメソッド名の指定が必要。第二引数はハッシュで、キー
to
に対する値がコントローラ名とメソッド名を#
でつないだ文字列。
9.5.3. リソースのルーティング¶
学生のコントローラは rails generate scaffold
で作った。
app/controllers/student_controller.rb
が出来ている。index
,create
,new
,edit
,show
,update
,destroy
というメソッドが自動的に用意される。
このようにCRUD操作(作成、編集、表示、削除など)が一通りできるものをリソースと言う。
これに対するルーティングは、操作ごとに書くのは面倒なので config/routes.rb
に resources :students
と一行書けば自動的に行われる。
9.5.4. ルーティングの確認¶
URLとメソッドの対応が見たい場合は、次のコマンドを実行する。
# rails routes -c students
Prefix Verb URI Pattern Controller#Action
students GET /students(.:format) students#index
POST /students(.:format) students#create
new_student GET /students/new(.:format) students#new
edit_student GET /students/:id/edit(.:format) students#edit
student GET /students/:id(.:format) students#show
PATCH /students/:id(.:format) students#update
PUT /students/:id(.:format) students#update
DELETE /students/:id(.:format) students#destroy
-c
オプションでコントローラを指定する。指定しないと全部出てくるが、大変見づらい。Prefix はヘルパーメソッドの名前などに使われるもの。
Verb はHTTPメソッドのこと。普通はGET、フォーム送信の時はPOST。それ以外は特別に指定しないと使われない。
URI Pattern はURLのアプリケーション名より後の部分。
(.:format)
はとりあえず無視してよい。Controller#Action はコントローラ名とメソッド名を
#
でつなげたもの。
9.5.5. 操作を限定したリソースルーティング¶
学部は個別ルーティングになっているが、リソースにするとヘルパーメソッド( faculty_path
など)が使えたりして便利。しかし、 index
や create
といった操作は用意していないので、使える操作を限定しないといけない。
config/routes.rb
の get 'faculties/:id'
のところを次のように書き換える。
resources :faculties, only: [ :show ]
only:
の後に、このリソースで使える操作(faculties
コントローラのメソッド名)をシンボルの配列で書く。操作は一般に複数個あるので、1個だけでも配列で指定する。
9.6. 今日のまとめ¶
課題16
前々回の課題で作った科目のモデル Course
について、コントローラとビューを作成せよ。ただし、URLと操作は次のようにする。
http://localhost:3000/courses で科目一覧と各科目の詳細ページへのリンクを表示
http://localhost:3000/courses/1 で1番の科目の詳細を表示(科目名と単位数。必修科目の場合はその旨を表示。)
提出は、科目のコントローラ、科目一覧のERBファイル、科目詳細のERBファイル、 config/routes.rb
をアップロード。
【解答例】
課題17
最終課題のアプリケーションについて、モデルとビューがどうなるか考えよ。
表示したい画面の構成を考え、絵を描いてみよ。
データベースに記録するデータには何があるか、表の項目を列挙してみよ。
【解答例】