【Rails】Routingの勉強
全体的な話
ルーティングは/config/routes.rbで制御する
ASP.NETのようにController側からAttributeで制御することはなさそう
現在のルーティングの一覧はrails routes
で確認できる
記法については具体的な記述例をコメントと共に見るのが早いと思う
基本的なルーティング
Rails.application.routes.draw do # root用のルーティング # sample_controllerのindex()を実行 root "sample#index" # GET /sample/new/ # sample_controllerのnew()を実行 get "sample/new" => "sample#new" # POST /sample/ # sample_controllerのcreate()を実行 # =>でもto:でもどっちでもいい post "sample", to: "saple#create" end
これをもってrails routes
をすると、
以下のように表示される
Prefix Verb URI Pattern Controller#Action root GET / sample#index sample_new GET /sample/new(.:format) sample#new sample POST /sample(.:format) saple#create
ここで出てきた(.:format)
というものについて、
まずRailsのルーティングでは()
で囲まれている部分は所謂Optionalなもの
なので上記の/sample(.:format)
は/sample
, /sample.json
, sample.html
にマッチする
(.:format)
じゃなくてHTMLだけにしたい時は色々指定する方法があるみたい
https://stackoverflow.com/questions/4579652/disable-format-routes-in-rails3
ついでにトレイリングスラッシュの有無はapplication.rb
で以下のように設定すればいい
config.action_controller.default_url_options = { :trailing_slash => true }
参考:
https://qiita.com/naokazuterada/items/5f4bbf82f1c99222dc53
パラメータを渡す
Rails.application.routes.draw do # 例えば [GET /user/11] のようなリクエストを送ると # user_controllerのshow()を実行し、 # showにはパラメータとして{id: '11'}が渡される get "user/:id" => "user#show" # GET /photo/01/234/ # photo_controllerのshow()を実行 # paramは {userid: '01', photoid: '234'} get "photo/:userid/:photoid", to: "photo#show" # default get "user/:id" => "user#show", defaults: {id: '111'} # matchとvia # show()に対してGET, POSTの両方をマッチさせる match "user", to: "user#show", via: [:get, :post] # constraints get "user/:id" => "user#show", constraints: {id: /[0-9]{8}/ } end
リソースベースでのルーティング
以下のサイトを見るのがわかりやすい
重要そうなとこだけ書き出す
リソースベースのルーティング (以下リソースルーティング) を使うことで、リソースベースで構成されたコントローラに対応する共通のルーティングを手軽に宣言できます。リソースフルなルーティングを宣言することで、コントローラのindex、show、new、edit、create、update、destroyアクションを個別に宣言しなくても1行で宣言が完了します。 https://railsguides.jp/routing.html#%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AE%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0-rails%E3%81%AE%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88
簡単にまとめると、リソースルーティングを使えば特定のリソースに関連するCRUD処理に対応するルーティングが一発で設定できるよ、というような感じ
このルールに則ればアクション名が散らないので確かに分かりやすいかも
(≒実質的に命名規則が定められる)
後述するcreateとかnewとか、あるいはgenerate, addあたりの語句は事実混ざりやすいし
(でもそんなルーティング一式全部定義することある?)
複数形リソース (resources)
複数存在するリソースに対してのルーティングはresourcesキーワードをもってルーティングを行う
上述のサイトのphotosでの例を実際に記述してrails routes
をするとこうなる
Rails.application.routes.draw do resources :photos end
Prefix Verb URI Pattern Controller#Action photos GET /photos(.:format) photos#index POST /photos(.:format) photos#create new_photo GET /photos/new(.:format) photos#new edit_photo GET /photos/:id/edit(.:format) photos#edit photo GET /photos/:id(.:format) photos#show PATCH /photos/:id(.:format) photos#update PUT /photos/:id(.:format) photos#update DELETE /photos/:id(.:format) photos#destroy
どのアクションが何をするものなのかは上記サイトを見るとわかりやすい
暗記のようなものなので慣れだと思う
単数形リソース (resource)
同様に単体でしか存在しないリソースに対してはresourceキーワードをもってルーティングを行う
以下の例はprofileというリソースでの例
ログイン中のユーザのprofileであれば単一みたいな...
Rails.application.routes.draw do resource :profile end
Prefix Verb URI Pattern Controller#Action new_profile GET /profile/new(.:format) profiles#new edit_profile GET /profile/edit(.:format) profiles#edit profile GET /profile(.:format) profiles#show PATCH /profile(.:format) profiles#update PUT /profile(.:format) profiles#update DELETE /profile(.:format) profiles#destroy POST /profile(.:format) profiles#create
複数形の時と違ってindexがなくなっていることと、IDによる指定がなくなっているのがわかる
単一のリソースであってその存在が保証されているならば、newとdeleteは要らない気がする
アクションを絞る (only)
以下のようにonlyで絞れる
Rails.application.routes.draw do resources :photos only: [:index, :show] resources :profile only: [:show] end
アクションを追加する (member)
以下のようにアクションを追加できる
Rails.application.routes.draw do resources :photos do member do get 'preview' get 'hoge' end end end
追加するアクションが一つならこの記法でもOK
Rails.application.routes.draw do resources :photos do get 'preview', on: :member end end
scope/namespace/module
どれもごっちゃになりそう
この記事が綺麗にまとまってるので見たほうがはやい
https://qiita.com/ryosuketter/items/9240d8c2561b5989f049
概要だけ引用
URL | ファイル構成 | |
---|---|---|
scope | 指定のパスにしたい | 変えたくない |
namespace | 指定のパスにしたい | 指定のパスにしたい |
module | 変えたくない | 指定のパスにしたい |
ルーティング用ヘルパー
ルーティングとして定義したURLやPATHはいい感じに呼び出せる
ルーティング
Rails.application.routes.draw do root "sample#index" get "test" => "test#index" get "hoge" => "hoge#index", as: :huga #asを付けるとhelperの名称が変わる resources :photos resource :profile end
定義
Prefix Verb URI Pattern Controller#Action root GET / sample#index test GET /test(.:format) test#index huga GET /hoge(.:format) hoge#index photos GET /photos(.:format) photos#index POST /photos(.:format) photos#create new_photo GET /photos/new(.:format) photos#new edit_photo GET /photos/:id/edit(.:format) photos#edit photo GET /photos/:id(.:format) photos#show PATCH /photos/:id(.:format) photos#update PUT /photos/:id(.:format) photos#update DELETE /photos/:id(.:format) photos#destroy new_profile GET /profile/new(.:format) profiles#new edit_profile GET /profile/edit(.:format) profiles#edit profile GET /profile(.:format) profiles#show PATCH /profile(.:format) profiles#update PUT /profile(.:format) profiles#update DELETE /profile(.:format) profiles#destroy POST /profile(.:format) profiles#create
Controller
class SampleController < ActionController::Base protect_from_forgery with: :exception def index @helpers = { :root_url => root_url, :root_path => root_path, :test_url => test_url, :test_path => test_path, # hogeはroutingで as: :hugaとしている # "hoge_url" => hoge_url, # "hoge_path" => hoge_path, :huga_url => huga_url, :huga_path => huga_path, :new_photo_url => new_photo_url, :new_photo_path => new_photo_path, # photo_**ではダメ :photos_url => photos_url, :photos_path => photos_path, :new_profile_url => new_profile_url, :new_profile_path => new_profile_path, } end end
html.erb
<% @helpers.each do |key, value| %> <%= key %>: <%= value %> <br/> <% end %>
出力
root_url: http://localhost:3000/ root_path: / test_url: http://localhost:3000/test test_path: /test huga_url: http://localhost:3000/hoge huga_path: /hoge new_photo_url: http://localhost:3000/photos/new new_photo_path: /photos/new photos_url: http://localhost:3000/photos photos_path: /photos new_profile_url: http://localhost:3000/profile/new new_profile_path: /profile/new
基本的にはpathを使い、リダイレクトの場合のみurlを使うとのこと
参考: