エンタープライズ領域での採用も増えてきたRuby on Railsを使ってWebアプリケーションを作るための入門連載。最新版の4に対応しています。今回は、MVCモデルにおける「C」の部分をつかさどるActionControllerの主な機能とアクションとパスの対応を定義するルーティングなどについて解説します。
前回の「ActiveRecordにおけるモデルの「関連」とコールバックの使い方」までではMVCモデルにおけるRailsのモデルをつかさどる機能を理解できたかと思います。
今回は、MVCモデルにおけるコントローラーをつかさどる「ActionController」の機能について解説していきます。ActionControllerは開発者が実装する各コントローラーの親クラスである「ApplicationController」の親クラスです。従って、開発者が実装する各コントローラーはActionControllerのメソッドを継承しています。
ActionControllerの機能に迫る前にコントローラーの基本について「book_library」のディレクトリ「06」を基におさらいしておきましょう。
サーバーにリクエストが来ると、ルーティングによってどのコントローラーのアクションを実行するかが決まります。
コントローラーはリクエストされたアクションを処理して出力を行います。その際、データはモデルオブジェクトとして取り扱われます。そして、データを当てはめたビューがレンダリングされ、レスポンスとして出力されます。コントローラーはそれらの処理の制御を担っています。
コントローラーは「rails g(enerate) controller」コマンドで作ることができます。引数には、まずコントローラー名、そして任意の数のアクション名を渡します。このコマンドはデフォルトではCSSやJavaScriptのアセットファイルとヘルパーも生成しますが、「--helper=false」「--assets=false」オプションをコマンドの最後に付けることで、それらを生成せず実行できます。
また、コントローラー名を「/」で区切り名前空間も設定できます。その際、ディレクトリ「admin」を「app/controllers」と「app/views」以下に作成し、そこにコントローラーを生成してくれます。
rails g controller admin/books --helper=false --assets=false
このコマンドで「Admin」という名前空間で「Book」モデルを管理する「Admin::BooksController」を生成しました。
コントローラーは「アクション」という単位でルーティングが割り当てられます。実装上はコントローラーのメソッドがアクションの処理を担っています。
リクエストがあると対応するコントローラーのインスタンスが生成され、さらに対応するアクションのメソッドが実行されます。
class Admin::BooksController < ApplicationController # indexアクション def index @books = Book.all end end
ルーティングは「config/routes.rb」で定義します。これまでの連載では「resources」による宣言で引数に渡したリソースに関するCRUD(読み込み、書き込み、更新、削除)機能のルーティングをまとめて定義していました。
# config/routes.rb BookLibrary::Application.routes.draw do resources :books resources :users end
ここには、この他にもさまざまなルーティングを定義する仕組みが用意されています。その中で最も基本的なのが「get」メソッドです。「get」メソッドはURLパターンと対応するコントローラー・アクションの情報をハッシュとして渡します。
resources :books resources :users get 'admin' => 'admin/books#index'
上のように「get」メソッドを加え、「rake routes」コマンドを実行すると最後に次の行が現れます。
admin GET /admin(.:format) admin/books#index
これは「/admin」にGETリクエストが来ると「Admin::BooksController」の「index」アクションを実行することを示しています。
アクションは特にリダイレクトしたり、レンダリングするビューを指定したりすることがなければアクション名と同じ名前を持つビューをレンダリングします。
先ほど定義した「admin/books#index」アクションのビューは以前「scaffold」コマンドで作成したものと同じ内容でもよいので、「app/views/books/index.html.erb」をコピーして使い回しましょう。
cp app/views/books/index.html.erb app/views/admin/books/index.html.erb
これでアプリケーションの機能が一つ追加されました。「rails s(erver)」コマンドでサーバーを起動し、「http://localhost:3000/admin」にアクセスして確認してみましょう。
ここからはActionControllerの各機能について詳しく見ていきます。まずはパラメーターについて解説していきます。
パラメーターにもいろいろ種類がありますが、Railsではどのようなパラメーターでも同じように扱えます。ですが、主に次の3種類のパラメーターがあることを覚えておくと理解がしやすくなります。
クエリ文字列パラメーターはURLの末尾に「?」を付けて、「&」で区切って加えることができます。
http://localhost:3000/admin?created_at_since=20140101&tagged=technology
上のURLでアクセスすると、「ActionController」でパラメーターを参照する「params」は次のオブジェクトを返します。
params => { "created_at_since" => "20140101", “tagged” => “technology”, "action" => "index", "controller" => "admin/books" }
ルーティングパラメーターは、ルーティングの定義でURLパターン内にパラメーターとする部分を設定しておくことで加えられるパラメーターです。「config/routes.rb」のルーティング定義に次の行を加えます。
get ‘admin/:id’ => ‘admin/books#show’
これにより「rake routes」コマンドで次のルーティングが増えているのが確認できます。
GET /admin/:id(.:format) admin/books#show
この行は「/admin/:id」にリクエストがあると「admin/books#show」アクションを実行することを示します。そして「:id」の部分がルーティングパラメーターの入る位置となり、次のURLでアクセスすると「params」はその下のようになります。
http://localhost:3000/admin/2
params => { "controller" => "admin/books", "action" => "show", "id" => "2" }
POSTデータパラメーターはPOSTメソッドによるリクエストに含まれるパラメーターです。
例として新しいBookを保存する「admin/books#create」アクションを作成してみましょう。次の「post」メソッドを使った定義を「config/routes.rb」に加えます。
post 'admin' => 'admin/books#create'
また、POSTデータパラメーターは次のようなフォームからのリクエストに含まれます。
<%= form_for @book, url: admin_path, method: 'post' do |f| %> <%= f.text_field :title %> <%= f.text_field :author %> <%= f.submit %> <% end %>
このフォームによって「admin/books#create」にPOSTリクエストが送られると「params」は次のようになります。
params => { "utf8" => "✔", "authenticity_token" => "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "book" => { "title" => "新しい本", "author" => "新しい作者" }, "commit" => "Create Book", "action" => "create", "controller" => "admin/books" }
Copyright © ITmedia, Inc. All Rights Reserved.