Rails アンチパターン - モノリシックなコントローラ(Monolithic Controllers)
引き続きRails AntiPatternsという本を読んでいます。
https://www.amazon.co.jp/dp/B004C04QE0/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1
前回は7 Testの1つめ「Fixture Blues」についてまとめました。
waterlow2013.hatenablog.com 今回は4 Controllersの4つめ「Monolithic Controllers」についてまとめます。
Monolithic Controllers
解決策有りきなのだが、REST原則に乗っていないコントローラをRESTに乗せる。 以下のようなサンプルがあったとする。
class AdminController def users #... if not params[:operation].nil? if params[:operation] == "reset_password" # ... end if params[:operation] == "activate_user" #... end if params[:operation] == "show_user" #... end end user_order = 'username' if not params[:user_sort_field].nil? user_order = params[:user_sort_field] # ... end end end
URLは以下になります。
POST /admin/users?operation=reset_password?id=x POST /admin/users?operation=delete_user?id=x POST /admin/users?operation=activate_user?id=x GET /admin/users?operation=show_user?id=x GET /admin/users
users
はアクションではなくリソース名であるべきなのでうつす。また、operationの中身をアクションに移動する。
urlは以下のように変わる。
POST /admin/users/:id/password DELETE /admin/users/:id POST /admin/users/:id/activation GET /admin/users/:id GET /admin/users
コードも変わる
class UsersController < ApplicationController def index # ... end def destroy # ... end def show # ... end end class PasswordsController < ApplicationController def create # ... end end class ActivationsController < ApplicationController def create # ... end end
config/routes.rb
は以下のようになる。
namespace :admin do resources :users do resource :passwords resource :activations end end
まとめ
index, new, create, edit, update, show, destroy以外のアクションがある場合や、アクションが7つに含まれていても1つのアクションが大きくなっている場合はRESTに寄せつつコントローラを分け、先に書いた7つのアクションに乗せるのがいいと思います。
DHHのコントローラの作り方の記事にも書いてましたね! postd.cc