Railsのルーティング(2)~RESTfulのカスタマイズ~
今回はresources/resourceメソッドの各種オプションを活用し、予め決められたマッピングルールをカスタマイズできる方法を連々書いていく
ルートパラメータの制約条件
例えばIDに3桁の数字を入れさせたくない場合やそのIDを入れられると困る場合などに使う。 (あとは予め渡される値がわかっている場合とか)
このように制限を儲けたい場合は「constraints」オプションをルートティングに記述してあげる
構文的には
パラメータ名: 正規表現パターン
の形式
例:
Railbook::Application.routes.draw do resources :book, constraints:{id: /[0-9]{1,2}/} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ end
これはbooksのリソースのidパラメータに対して「0~9の1~2桁の数値のみ適用」という設定をしている。
この条件に反したIDを入力した場合には
Routing Error No route matches [GET] "/books/10000"
というエラーが表示される
同一の制約条件を複数のリソースに付けたい場合には以下のように記述する
constraints(id: /[0-9]{1,2}/)do resources :books resources :reviews end
といったように記述する
正規表現では表現できない複雑な制約の定義
例えば現在の時刻によってルーティングを有効/無効を判定したい場合に使う
このような複雑な制約の定義をする場合
/models
フォルダに作成する
9~18時の間だけルーティングを有効にし、それ以外の時間帯でのアクセスを拒否するプログラムを作る
/model/TimeConstraint.rb
class TimeConstraint def matches?(request) current = Time.now current.hour >= 9 && current.hour < 18 end end
ここで重要になってくるのは matches?メソッド部分で、これは制約クラスであることを表している。 またmatches?メソッドを使う条件としては
・引数としてリクエスト情報(requestオブジェクト)を受け取り ・戻り値としてルートを有効にすべきかどうか(true/false)を返す
必要がある
上記のプログラムでは
Time.nowでシステムの現在時刻を取得し、その時刻が9~18時以外の時間帯にアクセスしようとしようとするとエラーが表示される
route.rbには以下の様な記述をする
require 'TimeConstraint' Railbook::Application.routes.draw do resources :books, constraints:TimeConstraint.new ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ end
formatパラメータの削除
そういやformatってなんだっけと調べてみると .xmlや.jsonのように拡張子の形式で出力フォーマットを指定することができる
リソースによっては複数のフォーマットに対応したくない場合に使うもの。
使い方はroute.rb
に
resources :books,format:false
とすればよい。
確認方法はrake routes
などで確認しformatが削除されてればおk
コントローラークラス/URLヘルパーの名前を修正する
resoures/resourceメソッドを使ってデフォルトで生成されたURLヘルパーの名前を変更したい場合は
controller/asオプションを指定する
マッピングすべきコントローラーや、生成するURLヘルパーの名前を変更することができる
route.rb
resources :users, controller: :members #1 resources :reviews,as: :comments #2
1では本来usersリソースを使う場合UsersControllerが対応しているはずだがこの文を記述することによって MembersControllerに対応付けてマッピングしている
2ではasオプションを指定することによってcomments_pathやcomment_pathなどのヘルパーが用意される。
モジュール配下のコントローラーをマッピング
コントローラークラスが多くなった場合コントローラーを特定のサブフォルダにまとめたい場合に使う その場合まずコントローラークラスを生成する
bundle exec rails generate controller Admin::Books
これはcontrollers/adminフォルダの配下にbooks_controller.rbという名前で生成しろって文。
(ちなみにモジュール対応のコントローラークラスに対してテンプレートを設置する場合には 「views/モジュール名/コントローラー名」のフォルダ配下に設置する (今回の場合だと/views/admin/books))
このようなモジュール対応のコントローラークラスに対して、RESTfulインターフェイスを定義するには namespaceブロックを利用する
routes.rb
namespace :admin do resources :books end
これによって/admin/booksや/admin/books/:idなどのURLパターン admin_books_pathなどのURLヘルパーが生成される
またモジュールだけ認識してURLヘルパーに影響をだしたくないならscopeを使う
scope module: :admin do resources :books end
これを行うとURLヘルパーやURLパターンにはモジュール名が含まれない (ちゃんと出来たかどうかはちゃんとrake routesで確認してね)
もう少しあるので一度ここで切る