[Rails]管理者コメント管理機能(ルーティング)(collection)
今回起きたエラー
ルーティングでこの書き方だと
namespace :admin do
resources :users, only: [:destroy]
resources :dashboards, only: [:index, :search]
resources :comments, only: [:index, :destroy]
resources :tasks, only: [:index, :destroy]
end
このエラーが出る。
admin_dashboards_search_path というルートが存在しないために発生している。
namespace :admin do
resources :dashboards, only: [:index, :search]
end
この部分でindex と search の 2つのアクション を定義しようとしているが
resources の only: には ルートのHTTPメソッド(index, show, new, create, edit, update, destroy など) しか指定できない。
しかし、 search はデフォルトのルートには含まれていないため、正しくルーティングが設定されない。
resources :dashboards
は index
と search
の 2つのアクション を定義しようとしているが、 resources
は ルートのHTTPメソッド(index, show, new, create, edit, update, destroy など) しか指定できない。
resourcesを宣言するだけで、コントローラのindex、show、new、edit、create、update、destroyアクションを個別に宣言しなくても1行で宣言が完了します。
引用元:Railsガイド
search
はデフォルトのルートには含まれていないため、正しくルーティングが設定できない。
解決策
collection
を追加する
search
は、特定の id
に依存しない検索アクションなので、 collection
を使って定義する。
collectionという用語は、複数の要素(要素のコレクション)を操作するルーティング(indexルーティングなど)を指します。
上のルーティングは、GETリクエスト + /photos/searchなどの(idを伴わない)パスを認識し、リクエストをPhotosコントローラのsearchアクションにルーティングします。このときsearch_photos_urlやsearch_photos_pathルーティングヘルパーも同時に作成されます。
引用元:Railsガイド
config/routes.rb
修正後の namespace :admin do
resources :users, only: [:destroy]
resources :dashboards, only: [:index] do
collection do
get :search
end
end
resources :comments, only: [:index, :destroy]
resources :tasks, only: [:index, :destroy]
end
解説
-
collection do ... end
を使うことで、search
アクションの ルートを明示的に追加 - これにより、以下のようなルートが生成される。
$ rails routes | grep admin
admin_dashboards_index GET /admin/dashboards(.:format) admin/dashboards#index
admin_dashboards_search GET /admin/dashboards/search(.:format) admin/dashboards#search
エラーその2
chatGPTは「上記修正をした後、form_with
の url:
はそのままOK。」と言っていたが、エラーが出た!なので、これは嘘!!
<%= form_with url: admin_dashboards_search_path, method: :get, local: true do |f| %>
パスヘルパー命名規則
毎回パスヘルパーの書き方で悩むので、まとめます!
Rails のルーティングのヘルパー名は、以下の 3つの要素の組み合わせ で決まる!
[アクション名] + [リソース名(複数形)] + path
🚀 ルートの種類ごとの命名規則
ルートの種類 | 記述方法 | URLパターン | 生成されるヘルパー名 |
---|---|---|---|
通常のリソース | resources :tasks |
/tasks |
tasks_path |
特定の ID を持つ単数リソース | resources :tasks |
/tasks/:id |
task_path(@task) |
collection で定義(IDなし) |
collection do get :search end |
/tasks/search |
search_tasks_path |
member で定義(IDあり) |
member do get :search end |
/tasks/:id/search |
search_task_path(@task) |
名前空間(namespace)あり | namespace :admin do resources :tasks end |
/admin/tasks |
admin_tasks_path |
名前空間 + collection | namespace :admin do resources :tasks do collection { get :search } end |
/admin/tasks/search |
search_admin_tasks_path |
名前空間 + member | namespace :admin do resources :tasks do member { get :search } end |
/admin/tasks/:id/search |
search_admin_task_path(@task) |
admin_dashboards_search_path
にならなかった
routes.rb
では次のように collection
で search
を定義 したから。
namespace :admin do
resources :dashboards, only: [:index] do
collection do
get :search
end
end
end
この場合の命名規則:
[アクション名] + [名前空間付きのリソース名] + path
= search + admin_dashboards + path
= search_admin_dashboards_path
admin_dashboards_search_path
ではなく search_admin_dashboards_path
になったのは、この命名ルールに従っているため!
admin_dashboards_search_path
にするには?
config/routes.rb
に as: "admin_dashboards_search"
を追加することで変更できます。
namespace :admin do
resources :dashboards, only: [:index] do
collection do
get :search, as: "admin_dashboards_search"
end
end
end
これを適用すると、命名規則が変わり:
[カスタム名] + path
= admin_dashboards_search + path
= admin_dashboards_search_path
参考文献
Discussion