0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Rails】Parameter Objectパターン

Last updated at Posted at 2022-09-16

環境

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

気をつけること

今回は必須パラメータが存在するかのバリデーションしか行っていないが、
フロントから渡された値の形式が正しいか(正しいメールアドレスの形式か)など、型が正しいかなどのフォーマットに関するバリデーションに留めた方が良い。
そうしないとパラメータオブジェクトの責務を超えてしまう。

データの整合性などの検証はモデル層でした方が良い。

参考

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?