基本中の基本のRouting設定の話になるのですが、改めて振り返ってみます。
基本の考え方
RailsではGET/POST/PUT/PATCH/DELETEの使用方法を明確に分けて考えます。
それぞれイメージとしてSQLと以下のように対応します。
method | SQL | 意味 |
---|---|---|
GET | SELECT | データの取得 |
POST | INSERT | データの作成 |
PUT/PATCH | UPDATE | データの更新 |
DELETE | DELETE | データの削除 |
SQLとひも付けての説明ですが、必ずしもDBのデータを弄らないときでも使います。例えば、ログインセッションの管理では、ログイン=セッションの作成と考えてPOSTを利用し、ログアウトはセッションの削除と考えてDELETEを利用します。
独自のアクションを作るときには意識するようにしましょう。
基本の使い方
RailsではRoutingの設定を行うためにconfig/routes.rb
を編集していきます。
基本的には何を操作する画面なのかを意識するためにresourcesを使って行きましょう。
config/routes.rb
resources :posts
こうすることで、自動的に以下の様なRoutingが設定されます。
基本の用途 | action | url | method |
---|---|---|---|
一覧画面 | index | /posts | GET |
詳細画面 | show | /posts/1 | GET |
新規作成画面 | new | /posts/new | GET |
編集画面 | edit | /posts/1/edit | GET |
データ作成 | create | /posts | POST |
データ更新 | update | /posts/1 | PUT/PATCH |
データ削除 | destroy | /posts/1 | DELETE |
不要なアクションの削除
先述の通り、resorces
メソッドでは様々なアクションが作られます。
ただ、必ずしも全て必要じゃないこともあります。
そのようなときに、不要なRoutingが残るのは美しくないですし、妙なセキュリティ・ホールになるかもしれません。
そのときは必要なものだけを残すようにしましょう。以下の例では「一覧画面」、「新規作成画面」、「データ作成」のみを残す設定です。
resources :posts, only: [:index, :new, :create]
また、これとは逆に利用しないアクションを指定することで、以下のようにもかけます。
resources :posts, except: [:show, :edit, :update, :destroy]
独自のアクションの作成
当然ながら、Railsは独自のアクションを定義することもできます。
例えば、CSVをダウンロードするアクションdownload_csv
として定義してみます。
CSVをダウンロードする使用を考えた時、考え方は2つあります。
- 全てのpostの内容をCSVとしてダウンロードするとき
- 指定されたpostの内容をCSVとしてダウンロードするとき
これらをそれぞれ書いてみます。
全てのpostの内容をCSVとしてダウンロードするとき
resources :posts do collection do get :download_csv # => /posts/download_csv end end
指定されたpostの内容をCSVとしてダウンロードするとき
resources :posts do member do get :download_csv # => /posts/1/download_csv end end
大きな違いはid
がURLに含まれるかどうかです。「指定されたpost」をid
として与えています。このid
はPostsController
内でparams[:id]
として参照することができます。
resourcesの入れ子
投稿にコメントが付いているときなど、関連するデータはしばしば、入れ子構造になります。
そのときroutesを入れ子にすることができます。
resources :posts do resources :comments end
こうすると、以下の様なURLでcommentsのコントローラにアクセスできるようになります。
基本の用途 | action | url | method |
---|---|---|---|
一覧画面 | index | /posts/1/comments | GET |
詳細画面 | show | /posts/1/comments/1 | GET |
新規作成画面 | new | /posts/1/comments/new | GET |
編集画面 | edit | /posts/1/comments/1/edit | GET |
データ作成 | create | /posts/1/comments | POST |
データ更新 | update | /posts/1/comments/1 | PUT/PATCH |
データ削除 | destroy | /posts/1/comments/1 | DELETE |
入れ子のURL設計にしておくと、下記のように、本来ありえないデータにアクセスすることによる、データの不整合を起こさないような実装が可能です。
app/controllers/comments_controller.rb
class CommentsController < ApplicationController
before_action :set_post
before_action :set_comment
def index
@comments = @post.comments
end
# 中略
private
def set_post
@post = Post.find(params[:post_id])
end
def set_comment
@comment = @post.comments.find(params[:id])
end
end
postの編集権限などを付けるとき、concernとして、まとめやすくなります。
欠点は長すぎるURLになることがあることですが、そうなってしまうときは、そもそも何か間違っている気がします。
まとめ
以上が一番、単純なRoutingの仕方になります。
もし、もっと複雑なURLを使いたいなどがあれば、match
を利用することでid
以外のパラメータをURLとして渡してやるなどのことが可能です。
- 基本はresourcesを利用する
- 不要なアクションへのroutingは必ず削除する
- has_manyな関係のデータへのRoutingは入れ子にする
以上を意識することで、綺麗にバグが少なく、実装が可能になるかと思います。
コメントを残す