内容
多対多モデルの機能を実装する際のルーティングで、moduleオプションを知らず少しはまったのでその内容・解決方法を投稿します。
今回考えるケース
管理者(admin)がスタッフ(staff)を操作(CRUD)でき、さらにstaffの写真を複数枚保存できるような仕様を考えます。
テーブルとしてはstaffsテーブル、imagesテーブル、中間テーブルにstaff_imagesテーブルがあるようなケースです。
ルーティングの実装
誤りの実装
あるスタッフに対し複数枚の写真を保存するので、resourcesを使えば実装できそうですね。以下のようにルーティングを実装してみます。
namespace :admin do
resources :staffs do
resources :images
end
end
$ rake routes | grep admin
admin_staff_images GET /admin/staffs/:staff_id/images(.:format) admin/images#index
POST /admin/staffs/:staff_id/images(.:format) admin/images#create
new_admin_staff_image GET /admin/staffs/:staff_id/images/new(.:format) admin/images#new
edit_admin_staff_image GET /admin/staffs/:staff_id/images/:id/edit(.:format) admin/images#edit
admin_staff_image GET /admin/staffs/:staff_id/images/:id(.:format) admin/images#show
PATCH /admin/staffs/:staff_id/images/:id(.:format) admin/images#update
PUT /admin/staffs/:staff_id/images/:id(.:format) admin/images#update
DELETE /admin/staffs/:staff_id/images/:id(.:format) admin/images#destroy
admin_staffs GET /admin/staffs(.:format) admin/staffs#index
POST /admin/staffs(.:format) admin/staffs#create
new_admin_staff GET /admin/staffs/new(.:format) admin/staffs#new
edit_admin_staff GET /admin/staffs/:id/edit(.:format) admin/staffs#edit
admin_staff GET /admin/staffs/:id(.:format) admin/staffs#show
PATCH /admin/staffs/:id(.:format) admin/staffs#update
PUT /admin/staffs/:id(.:format) admin/staffs#update
DELETE /admin/staffs/:id(.:format) admin/staffs#destroy
なぜ誤りなのか
よく見ると、コントローラのパスががadmin/images#index
のようになっています。これでは、staffの画像ではなくadminの画像のコントローラに思えてしまい、直感的ではありません。
どう直すべきか
このケースでは、URIではなくコントローラのパスだけ変えたいのでmoduleオプションを使用します。機能としては「スタッフ管理」になるので、staff_managementモジュールを作成しましょう。
正しい実装
正しいルーティングは以下のようになります。
namespace :admin do
resources :staffs, module: 'staff_magagement' do # moduleオプションを指定
resources :images
end
end
$ rake routes | grep admin
admin_staff_images GET /admin/staffs/:staff_id/images(.:format) admin/staff_magagement/images#index
POST /admin/staffs/:staff_id/images(.:format) admin/staff_magagement/images#create
new_admin_staff_image GET /admin/staffs/:staff_id/images/new(.:format) admin/staff_magagement/images#new
edit_admin_staff_image GET /admin/staffs/:staff_id/images/:id/edit(.:format) admin/staff_magagement/images#edit
admin_staff_image GET /admin/staffs/:staff_id/images/:id(.:format) admin/staff_magagement/images#show
PATCH /admin/staffs/:staff_id/images/:id(.:format) admin/staff_magagement/images#update
PUT /admin/staffs/:staff_id/images/:id(.:format) admin/staff_magagement/images#update
DELETE /admin/staffs/:staff_id/images/:id(.:format) admin/staff_magagement/images#destroy
admin_staffs GET /admin/staffs(.:format) admin/staff_magagement/staffs#index
POST /admin/staffs(.:format) admin/staff_magagement/staffs#create
new_admin_staff GET /admin/staffs/new(.:format) admin/staff_magagement/staffs#new
edit_admin_staff GET /admin/staffs/:id/edit(.:format) admin/staff_magagement/staffs#edit
admin_staff GET /admin/staffs/:id(.:format) admin/staff_magagement/staffs#show
PATCH /admin/staffs/:id(.:format) admin/staff_magagement/staffs#update
PUT /admin/staffs/:id(.:format) admin/staff_magagement/staffs#update
DELETE /admin/staffs/:id(.:format) admin/staff_magagement/staffs#destroy
上記のように、コントローラのパスも「admin/staff_magagement/images#index」となり、一目でstaffの写真を操作することがわかります。
最後に
モジュール名や、そもそも実装方法がRailsの「レールに乗っていない」場合教えて頂けると嬉しいです。
その他誤りなどもしありましたら指摘頂けると嬉しいです。