resources を nest するときは shallow を使うと幸せになれる
既にみんな使ってると思うけど、日本語の解説が見あたらなかったので一応書いた。
[crayon lang=”ruby”]
# config/routes.rb
resources :group do
resources :user
end
[/crayon]
こんな風にすると、新規に User を作る時の URL が /groups/:group_id/users/new となって、大変美しい。
ところが、いざ User が生成された後にその User を show するには /groups/:group_id/users/:id などとしなければならなくなる。
これは冗長である。 User の id が group に寄らず unique であるなら、 /users/:id で参照出来て然るべきだ。
そこで、shallow です。
[crayon lang=”ruby”]
# config/routes.rb
resources :group, shallow: true do
resources :user
end
[/crayon]
こうすると、なんと、
# rake routes group_user_index GET /group/:group_id/user(.:format) user#index POST /group/:group_id/user(.:format) user#create new_group_user GET /group/:group_id/user/new(.:format) user#new edit_user GET /user/:id/edit(.:format) user#edit user GET /user/:id(.:format) user#show PUT /user/:id(.:format) user#update DELETE /user/:id(.:format) user#destroy group_index GET /group(.:format) group#index POST /group(.:format) group#create new_group GET /group/new(.:format) group#new edit_group GET /group/:id/edit(.:format) group#edit group GET /group/:id(.:format) group#show PUT /group/:id(.:format) group#update DELETE /group/:id(.:format) group#destroy
な、なんて美しいんだ。。!
何が起きているかというと、user_id を指定しない action である index, new, create の3つは group_id を必要とし、それ以外の action では user_id のみを指定すればよい、ということに、たったの “shallow: true” だけでなってしまったのである。
もちろん、以下のように action を拡張した場合
# config/routes.rb resources :group, shallow: true do resources :user do get :search, on: :collection post :follow, on: :member end end
には、
# rake routes (抜粋) search_group_user_index GET /group/:group_id/user/search(.:format) user#search follow_user POST /user/:id/follow(.:format) user#follow
そうですそうです、そうして欲しかったんですよ、という状態にちゃんとなっている。
さらに深く resources を nest した場合にも、 shallow:true は1つだけで大丈夫。
# config/routes.rb resources :group, shallow:true do resources :user do resources :entry end end
この場合、entries#new は /user/:id/entries/new となり、 entries#show は /entries/:id となる。
shallow の挙動は、resources の nest 問題について一度もハマってみたことの無い人にはさっぱり理解出来ないような一見複雑な動作だが、物凄くよく考え抜かれている。Rails のこういうところが結構好きなのだな、僕は。
最後に、おそらく多くの方が form でつまずくと思うので、その時はこれを読みましょう: http://stackoverflow.com/a/9944554/683157