基本的なルーティング規則
現在のルートを見てみましょう。rake routes
:
$ rake routes Prefix Verb URI Pattern Controller#Action list_posts GET /list_posts(.:format) application#list_posts GET /show_post/:id(.:format) application#show_post new_post GET /new_post(.:format) application#new_post create_post POST /create_post(.:format) application#create_post GET /edit_post/:id(.:format) application#edit_post POST /update_post/:id(.:format) application#update_post POST /delete_post/:id(.:format) application#delete_post POST /create_comment_for_post/:post_id(.:format) application#create_comment POST /list_posts/:post_id/delete_comment/:comment_id(.:format) application#delete_comment list_comments GET /list_comments(.:format) application#list_comments
Rails規約の重要な洞察の1つは、データ中心のアプリ(または粗雑なアプリ)は、ユーザーがアプリケーションと対話できるようにするための非常に似た方法を持:
- 何かのリストを表示するページ
- 何かを表示する
- 何かの新しいインスタンスを作成するフォームを表示する
- 実際に何かを作成する
- 何かのイ
これらの七つの”相互作用パターン”は非常に一般的であり、railsはルーティングからコントローラ、ビュー、フォームへの強力な規則セットを提供し、これらのワークフ 我々は今、ルーティングの部分に焦点を当てるつもりです。
ルーティングについては、urlパターンを考え出す代わりに、RailsはUrlと対応するコントローラアクションを次のように構造化することを推奨しています:
ワークフロー | HTTP動詞 | パス | コントローラアクション |
---|---|---|---|
投稿のリストを表示 | GET | /posts | posts#index |
投稿を表示 | 取得 | /投稿/:id | 投稿#ショー |
投稿を作成するページを表示 | 取得 | /posts/new | posts#new |
ポストを作成する | ポスト | /posts | posts#create |
投稿を編集するページを表示する | GET | /posts/:id/edit | posts#edit |
投稿を更新する | PUT/PATCH | /posts/:id | posts#update |
投稿を削除する | 削除 | /posts/:id | 投稿#破棄 |
現在のルーティングのpost
部分をこの規則に従うように変更できます:
# posts GET /list_posts -> GET /posts posts#index GET /show_post/:id -> GET /posts/:id posts#show GET /new_post -> GET /posts/new posts#new POST /create_post -> POST /posts posts#create GET /edit_post/:id -> GET /posts/:id/edit posts#edit POST /update_post/:id -> PUT/PATCH /posts/:id posts#update POST /delete_post/:id -> DELETE /posts/:id posts#destroy
そして、routes.rb
ファイルで,
Rails.application.routes.draw do ### posts ### get '/posts' => 'posts#index' get '/posts/new' => 'posts#new' get '/posts/:id' => 'posts#show' post '/posts' => 'posts#create' get '/posts/:id/edit' => 'posts#edit' patch '/posts/:id' => 'posts#update' put '/posts/:id' => 'posts#update' delete '/posts/:id' => 'posts#destroy' # comments later.. ... end
この新しいパターンでは、URL自体には動詞がはるかに少なくなりますが、HTTP動詞に依存していることに注意してください(GET
/POST
/PUT
/PATCH
/DELETE
) それ以外の場合は同じURLパターンのセマンティクスを提供するには、例えば/posts/:id
。
PUT
は、PATCH
がこのアクションのより良い意味一致であると判断されるまで、リソースの更新に使用されていたことに注意してください。 それ以来、RailsはPATCH
を優先するように移行しましたが、両方の動詞を更新することができます。
後で見るもう一つの変更は、ApplicationController
のすべてを処理するのではなく、投稿に関連するすべてのUrlをPostsController
にルーティングすることです。 PostController
のアクション名
- new
- index
- show
- create
- edit
- update
- destroy
は、7つのインタラクションに対応する規約でもありますパターン。
これは、Railsがアプリケーション開発者としてあなたに課している最も強力な規則のセットです。 私たちはそれを暗記するための努力をするようにお願いします。 私たちは、あなたにもそれを行うのを助けるために、本を通してこの多くの時間を再訪します。
複数のリソースのルーティング
多くの場合、URLに複数のリソースが存在する必要があります。 たとえば、私たちのブログアプリでは、コメントを作成するルートが必要なときはいつでも、このコメントが作成された投稿を知ることが非常に重要
私たちは現在これをやっています:
post 'create_comment_for_post/:post_id' => 'application#create_comment'
複数の関連付けられたリソースを持つURLのRailsの規則は、”含む”リソースから”最も内側の”リソースまでのすべての方法で開始することです。 たとえば、コメントのルートは次のように変更されます:
post '/posts/:id/comments' => 'comments#create' delete '/posts/:post_id/comments/:id' => 'comments#destroy' get '/comments' => 'comments#index'
これらのUrlのセマンティクスは、”特定の投稿の下にコメントを作成する”と”特定の投稿の下にコメントを削除する”を表します。 最後のルート「システム内のすべてのコメントを表示する」は、投稿の下に「スコープ」する必要がないため、URLに「/posts」を付ける必要はありません。
Urlに複数のリソースがIdを持つ必要がある場合、最後のリソースがプレースホルダ:id
を使用し、残りのすべてが:resource_id
:post_id
などになります。
Restful
RESTは”Representational State Transfer”の略です。 これは、スケーラブルなwebサービスを作成するためのソフトウェアアーキテクチャ RESTは、webアプリケーションを構造化する方法として、それに多くの側面を持っていますが、webアプリ、Urlと対話するために使用するインターフェイスにどのよ
RESTがUrlのセマンティクスをどのように簡素化するかを見るために、例を見てみましょう。 オンラインピザ注文サービスを構築しているとしましょう。 サービスのインターフェイス(Url)の素朴な実装は次のようになります:
/check_order?order_id=2 /place_new_order /pizza_details?type=1 /pay_for_my_order?order_id=12 /cancel_order?order_id=3 /expedite_order?order_id=13
RESTfulなインターフェイス設計は次のようになります:
GET /orders/2 POST /orders GET /pizzas/1 POST /orders/12/payments DELETE /orders/3 POST /orders/13/expeditions
RESTfulインターフェイスは「名詞」または「リソース」を中心にしており、インターフェイスから「動詞」を削除しますが、代わりに標準化されたHTTP動詞に依存しています(GET
/POST
/PUT
/DELETE
) アクションのCRUDセマンティクスを提供する。 などの動詞check
, place
, cancel
取得するにはGET
、作成するにはPOST
、リソースを破棄するにはDELETE
のHTTP動詞に直接マップされますorder
。 pay
とexpedite
は、リソースorders
の下にpayments
とexpeditions
のサブリソースの作成(HTTP POST)として構造化されています。
RESTfulインターフェイスは、webアプリケーションの相互作用パターンを標準化し、理解しやすくプログラミングしやすくします。 インターフェイスはリソースの操作を中心としているため、応答ははるかに予測可能です。 RESTfulアーキテクチャパターンがwebサービスとの対話をどのように簡素化するかのアナロジーは、リレーショナルデータベースとSQL言語がデータ リレーショナルデータベースとSQLの前に、データは、通常、それらと対話するための特定のロジックを持つ独自のシステムに格納されていた、これはすべてのプ リレーショナルデータベースとSQLは、共通のデータ構造(テーブルに格納された行と列としてのデータレコード)と共通のインターフェイスのセットを与えた-の四つの簡SELECT
, INSERT
, UPDATE
そしてすべてのタイプの適用を支えることができるDELETE
。
WebアプリにRESTfulなインターフェイスを採用することで、バックエンドのデータがデータベースに格納される方法に合わせてアプリケーションを合理化し、開発を容易にすることができます。 私たちは、次の章でそれを見ることができます。
リソース表記
Railsのルーティング規則とRESTfulなURLパターンについて話しました。 ここで、routes.rb
ファイルは次のようになります:
### config/routes.rb ### Rails.application.routes.draw do ### posts ### get '/posts' => 'posts#index' get '/posts/new' => 'posts#new' get '/posts/:id' => 'posts#show' post '/posts' => 'posts#create' get '/posts/:id/edit' => 'posts#edit' patch '/posts/:id' => 'posts#update' put '/posts/:id' => 'posts#update' delete '/posts/:id' => 'posts#destroy' ### comments ### get '/comments' => 'comments#index' post '/posts/:id/comments' => 'comments#create' delete '/posts/:post_id/comments/:id' => 'comments#destroy' end
実際、posts
セクションにあるようなルートは非常に一般的なので、Railsはそれらを生成するのに役立つ特別なresources
表記を提供します。
私たちは簡単に行うことができます:
resources :posts
この行は、以前に持っていた8行を自動的に生成します。 update
アクションでは、互換性の理由から、RailsではPUT
とPATCH
の両方の動詞が許可されていることに注意してください。
コマンドライン環境でbundle exec rake routes
を実行すると、まったく同じルートセットが生成されることを確認できます。
この単線は8つのルートを生成することに注意してください。 私たちの場合、ここではすべてのルートが必要ですが、ルートのサブセットのみが必要な場合は、それらをより明示的に定義することができます:
resources :posts, only:
上記のこの行は、あなたのための3つのルートのみを生成します-それをチェックアウトするにはbundle exec rake routes
と入力します。
ネストされたリソース
Railsでは、リソースをネストして複数のリソースを持つURLパターンを作成することもできます。:
### config/routes.rb ### Rails.application.routes.draw do resources :posts do resources :comments, only: end resources :comments, only: :index end
bundle exec rake routes
を実行して出力を確認します-以前のものと同じである必要があります。
パスヘルパー
bundle exec rake routes
を実行すると、これらのルートの一部のPrefix
列に注意してください。 これらは、私たちのルートにRailsが提供するパスヘルパーを使用する方法を知るのに役立ちます。 コントローラとビューでこれらの接頭辞の後に_path
を使用して、パスを簡単に構築できます。例えば
:
posts_path # => '/posts' post_id = 123 post_comments_path(post_id) # => '/posts/123/comments'
コード内で/posts/123/comments
などのパスを直接コーディングするのではなく、URLヘルパーを使用する利点は何ですか? (例えば、あなたのコントローラのアクションで?)パスヘルパーを使用する理由は、アプリのURLパターンを変更する場合は、URLヘルパーを使用して別のパスを返す方がはるかに簡単だからです-例を見てみ:
get '/register', to: 'users#new', as: 'register'
このルートに”as”句を追加すると、bundle exec rake routes
を実行すると、Prefix
列にregister
が表示され、register_path
を使用して/register
パスを取得できます。 ここで、パスを/login
に変更したい場合は、次のようにするだけです:
get '/login', to: 'users#new', as: 'register'
今、私たちのregister_path
は私たちに/login
を与えます。 Railsアプリのコードをまったく変更する必要はありません。
その他のルーティング規則
先に進む前に、すでに見たもののいくつかのバリエーションと、Rails routingで利用可能なその他の機能を簡単に見てみましょう:
### config/routes.rb ### Rails.application.routes.draw do # pointing our homepage (root path) to posts#index root to: 'posts#index' # `match` & `via:` allow us to define one route and use several HTTP verbs # `as:` lets us define the name of the route prefix match '/authors/:id' => 'authors#update', via: , as: :update_author # update_author PUT|PATCH /authors/:id(.:format) authors#update resources :posts do # define extra params to pass for requests to a route get 'popular', on: :collection, action: :index, popular: true # popular_posts GET /posts/popular(.:format) posts#index {:popular=>true} get 'preview', on: :member # ... end # we can even use routes to redirect get '/home', to: redirect('/') end
上記のすべての機能を一度に1つずつ分解してみましょう。
-
root:
root
は、どのアクションが”/”(パスを持たないサイトのトップレベルURL)にマップされるかを指定するために使用されます。あなたのウェブサイト/アプリのルートURLが最も一般的に使用されているため、このroot
はroutesファイルの先頭に指定する必要があります。 -
マッチ+ビア:
match
は、URLパターンを一つ以上のルートに一致させるために使用されます。 また、このパターンでURLに一致させるためにどのHTTP動詞を使用できるかを指定することもできます。 これを行うには、match
メソッドにハッシュを渡します。 このハッシュのキーはvia
で、値はHTTP動詞の配列です。match
は、get
、post
、delete
など、より一般的に使用されるHTTPルーティングメソッドのより汎用的な形式です。 これらの方法と同じオプションをすべて取ることができますが、これらの方法と比較して、もう少し柔軟性があります。
たとえば、match
を使用して、2つの異なるHTTP動詞に対応する2つの異なるルートに一致するURLを指定することができます。 通常、これを行うには、1つではなく2つのコマンドが必要です。 この例では、URLパターン'/authors/:id'
をアクション'authors#update'
に一致させます。 次に、via:
を使用してそのURLの要求を発行するために使用できるHTTP動詞を指定します。match
を使用する場合は、常にHTTPメソッドを指定します。match
は、Railsの特定のアクションにルーティングするための別のオプションを提示します。 一般的には、get
やpost
など、より一般的に使用されるHttpHelpers
メソッドに固執することをお勧めします。 -
as:私たちは少し前に、オプション
as:
は、私たちのURLヘルパーの接頭辞を変更するために私たちのルート宣言で使用することができることを述べました。 これは、さまざまな方法で使用することができます。as:
を使用して、URLヘルパーをカスタムUrlとよりよく一致させることができます。 もう1つの用途は、現在のURLパスヘルパーを、より直感的なもの、またはアプリケーション内のリソースとよりよく一致するものに変更することです。 -
収集ルート:上記の
/popular
ルートをposts
リソースの下にネストする方法を参照してください。 次に、on: :collection
を使用して、このルートを入れ子にしているリソースのどの部分を指定します。 私たちは多くの投稿を持っているので、それはコレクションと考えられています。on: :collection
を指定すると、”URLとパス/posts/popular
を一致させます。”on: :collection
を追加しなかった場合、Railsはこのルートがpostsコレクションの単一のメンバーに関連付けられた別のリソースに対応していると仮定します。 その場合、私たちのルートは/posts/:id/popular
になります。 また、ブロック形式を使用して複数の収集ルートを指定することもできます。
collection do get 'popular' end
- 追加のパラメータを渡す:特定のUrlと一致したときに、
params
ハッシュで常に渡されるデフォルトのパラメータを指定できます。 これを指定するには2つの方法があります;1つの方法は上記の方法と同じです:
get 'popular', on: :collection, action: :index, popular: true
popular: true
人気のあるルートがparams
ハッシュを介して一致するアクションに渡されます。 キーは:popular
、値はtrue
になります。 また、ルートメソッドget
にハッシュを渡すことで、より明示的な構文を使用することもできます。
get 'popular', on: :collection, action: :index, defaults: { popular: true}
-
member route:
on: member
を使用して、ルートがコレクションのメンバーと一致することを指定できます。 これを使用すると、動的セグメントは:id
として表示されます。 URLヘルパーもpreview_post
として作成されます。 このルートをon: member
で指定することで、これがこの特定のリソースのメンバーであることをRailsに伝えています。 それは投稿の下にネストされた単なる別のリソースではなく、このアプリケーションの投稿により密接にリンクされているか、関連しています。 この形式は、複数のコレクションルートを定義するためのブロック形式と同じ構文を使用します。collection
をmember
に置き換えるだけです。 -
リダイレクト:上記の例では、それについて話すもう一つの概念が表示されており、それはリダイレクトです。 Railsは、ルートと一緒にリダイレクトヘルパーを使用して、あるパスから別のパスにリダイレクトする機能を提供します。
get '/home', to: redirect('/')
. 誰かがパス/home
にアクセスしようとすると、すぐにルートパス/
にリダイレクトされます。 これはもちろん1つのURLパスだけに限定されません。get '/home', to: redirect('/travel')
のようなものもあります。
レビュー
ルートは着信HTTP要求を解釈し、:
- HTTP動詞と要求URLパターンの組み合わせに基づいてコントローラアクションへの要求を一致させます
- コントローラアクションで
params
で利用できるようにURL内のデータをキャプチャ - Railsは、http動詞でリソースを操作する概念化により、ルートを設定するときにRESTful URLパターンを使用することを開発者に奨励しています。
-
resources
マクロを使用すると、RESTfulルートを非常に迅速に生成できます。