controllerに渡ってくるparamsを加工するためのラッパークラスです。
modelやqueryといったドメイン層に処理を渡す前にparamsを綺麗に加工することでドメイン層に無駄なロジックを書くことを防ぎます。
parameterのメリット
paramsで渡ってくる値の型の調整をすることができる
例えば
params[:id]
とした場合にidは文字列'1'
であるため、アプリケーション層で
params[:id].to_i
みたいな処理を書くことは多いですが、そういったロジックを書かなくてよくなります。
paramsに初期値を設定することができる
例えば
params[:id]
仮にparams[:id]
にnilが渡ってくるを想定して
params[id] ||= 1
みたいな処理を書くことは多いですが、そういったロジックもドメイン層に書かなくてよくなります。
参考コード
class RoomsParameter
def initialize(current_account, params={})
params.assert_valid_keys("room_name", "room_number", "candidate_ids")
@current_account = current_account
@room_name = params[:room_name] ? params[:room_name] : '部屋名未定'
@room_number = params[:room_number] ? params[:room_number].to_i : nil
@candidate_ids = define_candidate_ids(params[:candidate_ids])
end
def define_params
return {
id: @current_account.id,
room_name: @room_name,
room_number: @room_number,
candidate: @candidate_ids
}.with_indifferent_access.freeze
end
private
def define_candidate_ids(candidate_ids_params)
return [] if candidate_ids_params.nil?
candidate_ids_params << 1 if @current_account.candidate?
return candidate_ids_params
end
end
Roomモデルには検索メソッドが実装されているとします。
上記をコントローラー側でnewして、モデルに渡します。
def index
parameters = RoomsParameter.new(@current_account, params).define_params
@rooms = Room.search_rooms(parameters)
end
まとめ
アプリケーション層にあるべきparamsをparameterクラスで予め加工してしまうことで、ドメイン層でやるべきことをドメイン層で集中してやることができますが、最大のメリットはparameter層で加工済な分より安定したparamsをドメインに渡すことができるところではないでしょうか。
追記
paramsに対してhash.fetch(key, default)すると綺麗にまとまるかも。
参考文献
中規模Web開発のためのMVC分割とレイヤアーキテクチャ
rails で params に対して複雑な処理をするときのベストプラクティスは?