Railsルーティング②

Railsルーティング学習①の続き。

今回学べる内容は以下の通り。

 

先述した7つのHTTPメソッドだが、そもそもurlと_pathの違いがよくわからない。

_urlと_pathの違いは?

ざっくり、二つの違いは相対パス絶対パスかの違い。

_url絶対パスを指し*、_path*は相対パスを指す。

なんとなく主観をどこに置くかで相対化絶対に分けることができる。

_urlは他人視点で、_pathは自分視点。

他人から見て自分のアプリケーションの場所を探す時は絶対パスを参照しないとアプリにアクセスできない。

一方で、_pathは自分のアプリケーション視点なので、相対パスでアプリにアクセスできる。

実際にこの前作成したアプリのルーティングを見てみる。

Rails.application.routes.draw do
  root to: 'users#new'
  resources :optimes, :users
  get 'result', to: "optimes#result"
  end

上記のルーティングで作成されるPrefix, Verbは以下の通り。

Prefix Verb   URI Pattern                                                                                       Controller#Action
         root GET    /                                                                                                 users#new
      optimes GET    /optimes(.:format)                                                                                optimes#index
              POST   /optimes(.:format)                                                                                optimes#create
   new_optime GET    /optimes/new(.:format)                                                                            optimes#new
  edit_optime GET    /optimes/:id/edit(.:format)                                                                       optimes#edit
       optime GET    /optimes/:id(.:format)                                                                            optimes#show
              PATCH  /optimes/:id(.:format)                                                                            optimes#update
              PUT    /optimes/:id(.:format)                                                                            optimes#update
              DELETE /optimes/:id(.:format)                                                                            optimes#destroy
        users GET    /users(.:format)                                                                                  users#index
              POST   /users(.:format)                                                                                  users#create
    new_user  GET    /users/new(.:format)                                                                              users#new
    edit_user GET    /users/:id/edit(.:format)                                                                         users#edit
         user GET    /users/:id(.:format)                                                                              users#show
              PATCH  /users/:id(.:format)                                                                              users#update
              PUT    /users/:id(.:format)                                                                              users#update
              DELETE /users/:id(.:format)                                                                              users#destroy
       result GET    /result(.:format)                                                                                 optimes#result

このrootやoptimesのことをPrefixという。

Prefix + _urlもしくはPrefix + _pathでリンクを作成することができる。

pathとurlまとめ

#相対パス
root_path => '/'
new_path => '/new'
#絶対パス
root_url  => '<http://www.example.com/>'
new_url => '<http://www.example.com/new>'

_path

相対パス ・redirect_to以外で使用する。 ・link_toでよく使用されるイメージ

_url

絶対パス ・redirect_toの時にセットで使用する。(HTTPの仕様上、リダイレクトのときに完全なURLが求められるので)

_pathと_urlの違いについて調べてみた - Qiita

オブジェクトからパスを生成することもできる。

下記のように、食べ物に金額というネストされた中間テーブルがあるとする。

resources :foods do
  resources :prices
end

food_price_pathを使うと、idを数字で渡す代りにFoodPriceインスタンスを引数として渡すことができる。

# /food/:food_id/price/:price_id
<%= link_to 'price details', food_price_path(@food, @price) %>

これでそれぞれのidを指定して次のリンク先に遷移することができる。

今回のように複数のオブジェクトが集まったセットに対しては、url_forを使うことができる。

<%=link_to 'price details', url_for(@food, @price) %>

memberとcollection

7つ以外にRestfulなルーティングを追加したいときは、memberやcollectionを使って新しくルーティングを追加することができる。

二つの違いは、ざっくりroutingにidが付くか付かないかの違いにある。

下記2点を頭に入れた状態で、memberとcollerctionの具体的な違いに関して学習してみる

  • memberはidを使用して特定のデータにアクションを利用する
  • collectionはidを使わず全体のデータにアクションを利用する

member

resources :photos do
  member do
    get 'preview'
  end
end

上のルーティングはGETリクエストとそれに伴う/photos/1/previewを認識し、リクエストをPhotosコントローラのpreviewアクションにルーティングし、リソースid値をparams[:id]に渡している。同時に、preview_photo_urlヘルパーとpreview_photo_pathヘルパーも作成されている。

collection

resources :photos do
  collection do
    get 'search'
  end
end

上のルーティングは、GETリクエスト+/photos/searchなどの (idを伴わない) パスを認識し、リクエストをPhotosコントローラのsearchアクションにルーティングしている。

このときsearch_photos_urlやsearch_photos_pathルーティングヘルパーも同時に作成されている。

Rails のルーティング - Railsガイド

_pathメソッドと_urlメソッドの使い分け - Qiita