ルートとリソース

基本的なルーティング規則

現在のルートを見てみましょう。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動詞に直接マップされますorderpayexpediteは、リソースordersの下にpaymentsexpeditionsのサブリソースの作成(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ではPUTPATCHの両方の動詞が許可されていることに注意してください。

コマンドライン環境で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は、getpostdeleteなど、より一般的に使用されるHTTPルーティングメソッドのより汎用的な形式です。 これらの方法と同じオプションをすべて取ることができますが、これらの方法と比較して、もう少し柔軟性があります。
    たとえば、matchを使用して、2つの異なるHTTP動詞に対応する2つの異なるルートに一致するURLを指定することができます。 通常、これを行うには、1つではなく2つのコマンドが必要です。 この例では、URLパターン'/authors/:id'をアクション'authors#update'に一致させます。 次に、via: を使用してそのURLの要求を発行するために使用できるHTTP動詞を指定します。 matchを使用する場合は、常にHTTPメソッドを指定します。
    matchは、Railsの特定のアクションにルーティングするための別のオプションを提示します。 一般的には、getpostなど、より一般的に使用される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に伝えています。 それは投稿の下にネストされた単なる別のリソースではなく、このアプリケーションの投稿により密接にリンクされているか、関連しています。 この形式は、複数のコレクションルートを定義するためのブロック形式と同じ構文を使用します。collectionmemberに置き換えるだけです。

  • リダイレクト:上記の例では、それについて話すもう一つの概念が表示されており、それはリダイレクトです。 Railsは、ルートと一緒にリダイレクトヘルパーを使用して、あるパスから別のパスにリダイレクトする機能を提供します。get '/home', to: redirect('/'). 誰かがパス/homeにアクセスしようとすると、すぐにルートパス/にリダイレクトされます。 これはもちろん1つのURLパスだけに限定されません。get '/home', to: redirect('/travel')のようなものもあります。

レビュー

ルートは着信HTTP要求を解釈し、:

  • HTTP動詞と要求URLパターンの組み合わせに基づいてコントローラアクションへの要求を一致させます
  • コントローラアクションでparamsで利用できるようにURL内のデータをキャプチャ
  • Railsは、http動詞でリソースを操作する概念化により、ルートを設定するときにRESTful URLパターンを使用することを開発者に奨励しています。
  • resourcesマクロを使用すると、RESTfulルートを非常に迅速に生成できます。

コメントを残す

メールアドレスが公開されることはありません。