環境
Rails 6.0.1
Ruby 2.6.3
PostgreSQL 11.16
Parameter Objectパターン
Laravelだったらフロントから投げられたパラメータはRequest層でバリデーションをかけたりするが、
RailsはドキュメントにRequest層に当たるものが載っていない。
そういうときにParameter Objectパターンを使って実装するのもひとつの手法らしい。
app/models/parameters/profile_parameter.rb
module Parameters
class ProfileParameter
attr_reader :name,
:email,
:avatar,
:birthday,
:gender,
:phone_number,
:living_address,
:house_name,
:room_number
def initialize(opts = {})
update(opts)
end
def update(opts)
@name = attrs[:name] if attrs.key?(:name)
@email = attrs[:email] if attrs.key?(:email)
@avatar = attrs[:avatar] if attrs.key?(:avatar)
@birthday = attrs[:birthday] if attrs.key?(:birthday)
@gender = attrs[:gender] if attrs.key?(:gender)
@phone_number = attrs[:phone_number] if attrs.key?(:phone_number)
@living_address = attrs[:living_address] if attrs.key?(:living_address)
@house_name = attrs[:house_name] if attrs.key?(:house_name)
@room_number = attrs[:room_number] if attrs.key?(:room_number)
validate!(opts)
self
end
def attributes
{
name: name,
email: email,
avatar: avatar,
birthday: birthday,
gender: gender,
phone_number: phone_number,
living_address: living_address,
house_name: house_name,
room_number: room_number
}.compact
end
private
def validate!
raise_bad_request if name.blank?
raise_bad_request if email.blank?
raise_bad_request if birthday.blank?
raise_bad_request if phone_number.blank?
end
def raise_bad_request
raise ActionController::BadRequest, '必須項目が入力されていません'
end
end
end
end
Parameterオブジェクトをnewしてすでにバリデーションされたprofile_params.attributes
をupdateに渡せる。
app/controllers/profiles_controller.rb
def update
profile_params = Parameters::ProfileParameter.new(params)
current_user.update(profile_params.attributes)
...
end
気をつけること
今回は必須パラメータが存在するかのバリデーションしか行っていないが、
フロントから渡された値の形式が正しいか(正しいメールアドレスの形式か)など、型が正しいかなどのフォーマットに関するバリデーションに留めた方が良い。
そうしないとパラメータオブジェクトの責務を超えてしまう。
データの整合性などの検証はモデル層でした方が良い。
参考