Help us understand the problem. What is going on with this article?

Railsアプリケーションでより良いリソース設計を実装するためのテクニック

More than 3 years have passed since last update.

shallowを使って無意味なネストをなくす

ルーティングを書くときは、意味のないネストが生まれないように気をつける。

例えば、各モデルのprimary keyidで、ユーザーid: 100の記事id: 200を次のようなルーティングで示しているとする。

resources :users do
  resources :articles
end
METHOD PATH
ユーザーが投稿した記事の一覧 GET /users/100/articles
記事の詳細 GET /users/100/articles/200
記事の編集 GET /users/100/articles/200/edit

というルーティングになる。この時、1件の記事を対象とするリソースに、ユーザー情報は対象のリソースとは関係ないのでリソースに含まれるべきではない。(また、権限の情報はリソースそのものの情報とは関係ない。)

ルーティングはあくまでどのリソースを対象にしているかを考えるべきである。

shallowオプションを使えば、このユーザーによる無駄なルーティングのネストをさけて、あるべきルーティングを作ることができる。

resources :users, shallow: true do
  resources :articles
end
METHOD PATH
ユーザーが投稿した記事の一覧 GET /users/100/articles
記事の詳細 GET /articles/200
記事の編集 GET /articles/200/edit

動詞を含まない

パスの中に、動詞を含めるべきではない。

リソースの操作は、取得・作成・削除・更新で表現でき、これらは全てHTTP Request methodで表現ですべきです。

リソースの操作の安全性や冪等性によって、どのRequest methodを使うか選択します。

METHOD
GET / HEAD  リソースの取得
POST  リソースの破壊的変更、冪等でない
PUT / PATCH リソースの更新、冪等である
DELETE リソースの削除、冪等である

リソースの操作を index show create update destroyで表現できないか考える

多くのリソースの操作は index show create update destroy で表現できる。

できるだけこれらのアクションで表現することによって人間にとって理解しやすいルーティングを実現することができる。

(サーバーサイドレンダリングを利用するアプリケーションでは new editも使うとよい。)

「DHH(Railsの作者)はどのようにRailsのコントローラを書くのか」という記事が参考になる。

singular resourceを使う

親リソースに紐づく子リソースが必ず1つしか存在しないhas-one関連のリソースは、singular resourceをりようして表現する。

例えばユーザーが一つのプロフィールを持つという構造を表現する。

resources :users do
  resource :profile
end
  • app/
    • controllers/
      • users_controller.rb
      • profiles_controller.rb
PATH
プロフィールの詳細 /users/100/profile
プロフィールの登録 /users/100/profile/new
プロフィールの編集 /users/100/profile/edit

render / redirect_toの使い分け

リクエストの処理の終了後にredirectすべきか、renderingをすべきかを考える。

判断基準の一つとして、その処理が成功・失敗した後の対象のリソースが変化しているかどうかをみる。

リソースの作成処理を行った後に作成したリソースの詳細画面を表示するのであれば、現在のパスでは存在しないリソースの取得をすることになるのでリダイレクトが必要であるし、削除した後に一覧画面に遷移する場合も同様にリダイレクトが必要です。

一方で、詳細画面(show)から同じリソースの更新をして同じリソースの詳細画面をもう一度表示する場合は取得するとなる対象リソースと更新する対象リソースが全く同じなのでリダイレクトする必要はない。

検索 / filter 系はGET QUERYを使う

検索や、簡易的なリソースのフィルタリングはGETクエリを使う。

例: /articles?tag=書評
例: /search?q=日記

また、あるリソースに紐づくリソースの一覧を表示する場合等、has-many関連のリソースを表現する場合はネストしたほうが明確である。

例: /categories/1/articles

params[:id]はなにか

:idはデータベースに登録しているrecordのidを表しているのではない。

リソースを一意に識別する符号であるということを意識する。

そのリソースが、年月日に紐付いて1日に1つのリソースを持つものであれば、テーブル構造に関係なく、idは年月日を示すものになるべきである。

例: /schedules/2016-12-04

書籍

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away