第7回 Ruby on Rails〜その他の重要な要素①(ルーティング)〜

Ruby

はじめに

ここまではタスク管理アプリを作りつつRuby on Railsの基本的な機能や考え方、テストについて学習してきました。

しかし、Railsにはまだまだ触れていない要素がたくさんあります。
ここからは、これまで取り上げることのなかったいくつかの重要な要素について学習していきます。

具体的には特に重点的に理解が必要だと思われる以下の要素について学習していきます。

  • ・ルーティングの詳細
  • ・国際化
  • ・日時の扱い
  • ・エラー処理のカスタマイズ
  • ・セキュリティ
  • ・アセットパイプライン
  • ・production環境

この中から今回は「ルーティングの詳細」について学習します。

ルーティング

ルーティングについては以前簡単に学習しましたが、「どのようなURLへどのようなHTTPメソッドでアクセスされたら、どのコントローラのどのアクションを呼び出すか」をconfig/routes.rbに定義します。アクセスを受けて適切なアクションへと案内する仕組みをルーティングと呼びます。

また、Railsのルーティングを理解する上で、ルーティングの仕組みに大きな影響を与えている「RESRful」という概念についても併せて学んでいきます。

「ルート」を構成する5つの要素

ルーティングは、リクセストをアクションへと道案内する「ルート」の集合体として捉えることができます。以下はルートの主な構成要素です。

これらの要素の利用パターンは2つあります。

基本的にルートはHTTPメソッドとURLからアクションに案内するための定義ですが、もう一つの働きとして、URLパターンに名前をつけておいて、その名前を元にURLを簡単に生成するためのヘルパーメソッドを作り出します。

ルートの定義

前述の5つの要素を持ち、アクションへの案内とURLヘルパーメソッドの生成の2つの働きをする1つのルートを定義してみます。

まずはログイン機能の実装の際に書き足した以下の2つの定義について確認します。

/config/routes.rb

get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'

上記の定義はそれぞれ次のような意味になります。

「GETメソッドで、/loginというURLに対してリクエストが来たら、SessionsControllerのnewアクションを呼び出す。また、/loginというURLを、login_pathというヘルパーメソッドで生成できるようにする。」

「POSTメソッドで、/loginというURLでリクエストされた時に、SessionsControllerのcreateアクションを呼び出す。URLパターン名は先の定義と同じloginとする。」

複数のルートのURLパターンが同じ場合は、基本的に同じURLパターン名をつけて、同じURLヘルパーメソッドを利用することが多くなっています。

routes.rbの定義はrails routesというコマンドを実行することで確認できます。

$ rails routes
Prefix Verb   URI Pattern                                                                                            
      Controller#Action
 login GET    /login(.:format)                                                                                   
       sessions#new
        POST   /login(.:format)                                                                                  
       sessions#create

getなどの代わりにmatchと:viaオプションの組み合わせを使うと、複数のHTTPメソッドを受け付ける1つのルートを定義できます。

例えば、sessions#createをPOSTの時だけでなくPATCHやPUTでリクエストされた際も呼ぶ場合、次のように記述します。

match '/login', to: 'sessions#create', via: [:post, :patch, :put]

RESTfulの概要

前節でルートを定義する方法を学んだので、次は複数ルートの定義についてみていきます。ただしその前に、ルートをどのように設計すべきなのかとういうことに関連する「RESTful」という指針について見ていきます。

「RESTful」は、REST(REpresentational State Transfer)という設計原則に従うシステムを指します。RESTの設計原則は以下の通りです。

  1. HTTPリクエストはそのリクエストで必要な情報をすべて持ち、前のリクエストの状態が保存されている必要がない(ステートレス)
  2. 個々の情報(リソース)への「操作」の表現がHTTPメソッドとして統一されている
  3. 個々の情報(リソース)がそれぞれ一意なURIで表される
  4. ある情報(リソース)から別の情報を参照したいときは、リンクを利用する

このうち、Railsのルーティングを理解する上で一番重要なのは2ですが、他の項目もRailsのルーティングやコントローラの設計を行う上で重要です。

Railsは、アプリケーションをRESTfulなシステムとして開発しやすくする機能を提供しており、以下のような特徴があります。

  • ・URLが表す情報のことをリソースと呼ぶ。
  • ・2の理由により、GET/POSTだけでなくPATCH,PUT,DELETEなどのHTTPメソッドをサポートする。
  • ・2の理由により、RESTfulなシステムでは、操作はHTTPメソッドで表現し、URLで表現しない。URLはなるべく情報(リソース)の名前を表す「名詞」にするという発想で作られている。

RESTfulなインターフェイスのメリットは、美しく分かりやすいインターフェイスを実現できることの他に、Railsのレールに乗れる、URLやHTTPメソッドを考える時間の節約、他者が設計を理解しやすくなる、などの点があります。

RESTfulなインターフェイスについて見ていきます。

例えば、参照は「リソース〇〇を取得したい」というリクエストになります。取得操作を表すHTTPメソッドはGETです。そのためタスク一覧を取得したい場合は「GET/tasks」というインターフェイスが望ましいです。特定の一つのリソースを取得する場合は、「GET/tasks/3」となります。

登録の実行(create)の場合は、登録後に所属することになる親に当たるリソースに対して、新しい情報を送るイメージで「POST/tasks」で実現します。

このように、CRUDを実現するための他のアクションについてもRESTfulな設計パターンを考えることができます。そのような設計パターンをもとに、よくあるCRUDアクションのルーティングを一括で登録できるようにするのが次節で説明するresourcesという機能です。

resourcesによるルート定義

現在タスク管理アプリのタスク管理のルーティングは以下のようになっています。

/config/routes.rb

resources :tasks

Railsでは一覧・詳細・登録・更新・削除といっったよくある機能群に必要なルート一式をresourcesメソッドを使って定義できます。resourcesを使うことで一気に7つのアクションに対応する7つのルートを定義できます。

resources :tasksによってまとめて定義されるルートは以下の通りです。

resourcesメソッドは:onlyオプションまたは:exceptオプションを使うと特定のアクションのルートだけを作成できます。

以下の例ではindexアクションのルートのみ作成します。

/config/routes.rb

resources :tasks, only: [:index]

以下の例ではdestroy、edit、indexアクション以外の4つのルートを作成します。

/config/routes.rb

resources :tasks, except: [:delete, :edit, :update]

また、resourcesにブロックを渡し、member, collection, newなどを挟んで次のように独自のアクションをためのルートを合わせて定義することができます。

以下の例では、/tasks/exportというURLをexportアクションに対応づけます。

/config/routes.rb

resources :tasks do
 colloction do
  get 'export'
 end
end

このようにresourcesを使うことでバリエーション豊富な定義が可能です。

routes.rbの構造化

ルートを定義する記述は、前提となるURL階層やコントローラクラスを就職するモジュール、コントローラクラス、URLパターン名のプリフィックスなどで構造化することができます。

構造化のためのメソッドとしてはscope、namespace、controllerなどがあります。

  • ・scope…URL階層(:path)、モジュール(:module)、URLパターン名のプリフィックス(:as)などをオプションに指定して、ブロック内の定義にまとめて一定の制約をかけます。
  • ・namespace…URL階層、モジュール、URLパターン名に一括で一定の制約をかけます。scopeと違って一括なので、URL階層にだけ制約をかけるなどはできません。
  • ・controller…コントローラを指定します。

以下はnamespaceを使用した例です。Admin::UserControllerのCRUDを、/admin/usersといったURL、admin_users_pathといったURLヘルパーメソッドと共に実現します。

/config/routes.rb

namespace :admin do
 resources :users
end

このようにしてルートを定義する記述を構造化できます。

終わりに

今回はこれまで学習していなかったRailsの重要な要素の学習として、ルーティングについてまとめました。

基本的なルートの書き方、RESTfulという概念について触れ、resourcesを利用したルート定義についてまとめました。

次回以降もまだ学習していないRailsの重要な要素についてまとめていきます。

コメント

タイトルとURLをコピーしました