環境
Rails 6.0.1
Ruby 2.6.3
PostgreSQL 11.16
NGパターン
Parameter層(ActiveRecordを継承しないモデル)で、独自で必須のバリデーションメソッドをつくらない。
module Parameters
class PostParameter
attr_reader :params
def initialize(params)
permitted_params(params)
validate!
end
def attributes
{
title: params[:title],
content: params[:content]
}.compact
end
private
def validate!
if params[:title].blank? || params[:content].blank?
raise ActionController::BadRequest, '必須項目が入力されていません'
end
end
end
end
OKパターン
ActiveModel::Model
をincludeすることでバリデーションできる。
module Parameters
class PostParameter
include ActiveModel::Model
attr_accessor :title,
:content,
validates :title,
:content,
presence: true
def attributes
validate!
{
title: title,
content: content
}.compact
end
end
end
例としてわかりやすいようにしてるのでこれだけのバリデーションだけならパラメーター層にしなくても良さそうだが、パラメータ層ではやるとしても、フロントから渡された値の形式が正しいか(正しいメールアドレスの形式か)など、型が正しいかなどのフォーマットに関するバリデーションに留めた方が良い。
そうしないとパラメータオブジェクトの責務を超えてしまう。
module Api
class PostsController < Api::ApplicationController
def create
notification_params = Parameters::PostParameter.new(permitted_params)
current_user.create_post(notification_params)
...
end
private
def permitted_params
params.permit(
:title,
:content,
)
end
end
end
参考