【Rails】routesの設定で「resource」と「resource"s"」の違いで小一時間悩んだ話
DELETEのrouteに:idと:user_idの2つ現れてしまった
routesをネストした時に、resourcesと単数形でなかればならないところを複数形で書いてエラーになりました。なんのこっちゃだと思うのでまずはコードを見てください。
# 誤ったコード Rails.application.routes.draw do # (中略) resources :users do resources :relationships, only: [:create, :destroy] end resources :records end
resources :users
にrelationships
がネストされていると思います。
目的としては、/users/:user_id/relationships
のようなパスにしたかったためです。これだと、relationships
リソースでuser_idが利用しやすくなるからです。
ただ、実際にroutesを確認してみると目論見とは異なるルートとなっていました。
$ docker-compose run web rails routes => Prefix Verb URI Pattern Controller#Action about GET /about(.:format) static_pages#about login GET /login(.:format) sessions#new POST /login(.:format) sessions#create logout DELETE /logout(.:format) sessions#destroy root GET / users#index user_relationships POST /users/:user_id/relationships(.:format) relationships#create user_relationship DELETE /users/:user_id/relationships/:id(.:format) relationships#destroy # (以下略)
上記のここです
user_relationships POST /users/:user_id/relationships(.:format) relationships#create user_relationship DELETE /users/:user_id/relationships/:id(.:format) relationships#destroy
POSTの方は問題ないのですが、DELETEの方は:user_id
と:id
の2つの要素が入ってきてしまって今回は困ってしまいました。これは典型的なfollow/follower機能の実装で、followerのdeleteでは:user_id
の方しか使わないからです。かといって、:id
の方を放置していいのかというと、それはルートエラーになります。
複数無いものは「resouce」を使う
結論を申し上げますと、ネストの中の:relationshipsのresourcesを単数のresourceにすると上手く行きました。
# 修正したコード Rails.application.routes.draw do # (中略) resources :users do resource :relationships, only: [:create, :destroy] end resources :records end
種がわかれば当たり前のことですが、複数形resourcesということは複数あると宣言しているわけですから、:idや:user_idなどで枝番が付くわけです。
当たり前だろ!っとお思われる方も多いと思いますが、少しググったところで明確に注意喚起しているページもありませんでしたので書いてみました。
$ docker-compose run web rails routes => Prefix Verb URI Pattern Controller#Action about GET /about(.:format) static_pages#about login GET /login(.:format) sessions#new POST /login(.:format) sessions#create logout DELETE /logout(.:format) sessions#destroy root GET / users#index user_relationships DELETE /users/:user_id/relationships(.:format) relationships#destroy POST /users/:user_id/relationships(.:format) relationships#create # (以下略)