LoginSignup
1
0

More than 1 year has passed since last update.

【Rails】ActiveRecordを継承しないモデルのバリデーションはActiveModel::Modelをincludeしよう

Posted at

環境

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

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0