なんか毎回忘れたころに書くことになってその度にググってるので、書き留めておく。
resources
にresource
を直接ネストさせると、親のuser_id
がURLに入る。
routes.rb
resources :users, only: %i() do
resource :password, only: %i(update)
end
% rake routes
user_password PATCH /users/:user_id/password(.:format) passwords#update
PUT /users/:user_id/password(.:format) passwords#update
User
とPassword
のようなリクエストユーザが自身のリソースのみにアクセスできるような親子パターンでは、リクエストしたユーザ自身のuser_id
以外を指定できるようなURLはパラメータが無意味になるだろうし、user_id
はURLパスから取り除きたい。
アクションメソッドをusers_contorller.rb
に書いてしまうパターン。
routes.rb
resources :users, only: %i() do
patch :password, on: :collection
end
# or
resources :users, only: %i() do
collection do
patch :password
end
end
% rake routes
password_users PATCH /users/password(.:format) users#password
しかし、この方法だとuser
リソースのためのメソッドとコンフリクトしないために、大抵のパターンで:edit_password
や:update_password
などのルートを作ることになりアクションの名前にいびつさが出てくる。
別のコントローラファイルを作って親と同じくscaffold
パターンのアクションを追加したい。
routes.rb
resources :users, only: %i() do
collection do
resource :password, only: %i(edit update)
end
end
% rake routes
edit_password GET /users/password/edit(.:format) passwords#edit
password PATCH /users/password(.:format) passwords#update
PUT /users/password(.:format) passwords#update
コントローラファイルのパスもURLと合わせたいので、さらにcontroller
もしくはto
オプションを追加する。
routes.rb
resources :users, only: %i() do
collection do
resource :password, only: %i(edit update), controller: 'users/password'
end
end
% rake routes
edit_password GET /users/password/edit(.:format) users/password#edit
password PATCH /users/password(.:format) users/password#update
PUT /users/password(.:format) users/password#update