はじめに
「〇〇さんのブログ記事」のようなページを作成する際、ルーティングの書き方を迷ったのでネストされたリソースのルーティングについてまとめます
やりたいこと
〇〇さんのブログ記事ページを作成したい
(〇〇さん以外のブログ記事はページに表示しない)
この場合、〇〇さんにブログ記事をネストすると簡単にできる
MemberとEntryモデルが存在し、1対多で関連づけられているモデル
has_many :entries
belongs_to :member
→Memberモデルの下にEntryモデルをネストする
ルーティングの書き方
resources :members do
resource :entries
end
このルーティングによって、entriesControllerのアクションは以下のパスでアクセスできるようになる
| アクション | パス | HTTP |
|---|---|---|
| index | members/123/entries | GET |
| show | members/123/entries/456 | GET |
| new | members/123/entries/new | GET |
| edit | members/123/entries/456/edit | GET |
| create | members/123/entries | POST |
| update | members/123/entries/456 | PATCH |
| destroy | members/123/entries/456 | DELETE |
idが123の会員の記事一覧ページ・・・indexアクション
members/123/entriesでアクセスが可能
idが123の会員の456の記事詳細ページ・・・showアクション
members/123/entries/456でアクセスが可能
パラメータ取得について
123・・・params[:member_id]
456・・・params[:id]
ネストされたリソースへのリンクを作成する場合
| アクション | パスを返すメソッド |
|---|---|
| index | member_entries_path(@member) |
| show | member_entries_path(@member, @entry) |
| 〜省略〜 |
entriesControllerのアクションのパスでidを指定するモデルを引数に指定する必要があります
※members/123/entriesの場合はmember.idが指定されているので引数にmemberは必要となる
パスを返すメソッドの代わりの配列を指定する場合
| アクション | パスを表す配列 |
|---|---|
| index | [@member, :entries] |
| show | [@member, @entry] |
| new | [:new, @member, :entries] |
| edit | [:edit, @member, @entry] |
| create | [@member, :entries] |
| update | [@member, @entry] |
| destroy | [@member, @entry] |
ネストする・しない混合したルーティングも可能
resources :members do
resource :entries, only: [:index]
end
resource :entries
indexアクションはネストしたパスmembers/123/entriesでも、ネストしていないentriesでもアクセスが可能となる
余談・・・
only: [:index, :show]の記載をすると、indexアクション・showアクションのみのルーテングが作成されるが、only: []の記載をすると、すべてのアクションを無効化することができる
参考
【Rails】1対1のアソシエーションにおけるネストされたリソース設計について
【Rails】ネストしたresourcesをフル活用したアプリケーションの作成方法|_url, _path, form_with modelのエラー対処法