scaffold を制するものは rails を制す、という言い伝えがありますが、 rails g scaffold User
などとすると routes.rb に突如現れるのが、 resources というやつです。
いまここに、Group と User という2つのモデルがあり、 Group が has_many :users
で、 User が belongs_to :group
だとしましょう。よくある関係ですね。
このような場合に、resources を
resources :group do
resources :user
end
こんな風に nest すると、新規に User を作る時の URL が /groups/:group_id/users/new となり、自然な形で group_id を渡すことができます。
ところが、このように routes を定義すると、いざ User が生成された後にその User を show するには /groups/:group_id/users/:id などとしなければならなくなってしまいます。
これは冗長ですね。 User の id が group に寄らず unique であるなら、 /users/:id で参照出来て然るべきです。
そこで、shallow です。
resources :group, shallow: true do
resources :user
end
こうすると、なんと、
# 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 を拡張した場合
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
ご覧の通り、 on: :collection で定義した :search の方にのみ、:group_id が必須になっています。
そうですそうです、そうして欲しかったんですよ!
さらに深く resources を nest した場合にも、 shallow:true は1つだけで大丈夫。
resources :group, shallow:true do
resources :user do
resources :entry
end
end
この場合、entries#new は /user/:id/entries/new となり、 entries#show は /entries/:id となります。
最後に、おそらく多くの方が form でつまずくと思うので、その時はこれを読みましょう: http://stackoverflow.com/a/9944554/683157
Author: kuboon