【rails】バリデーションを別ディレクトリに分けたい

やりたいこと

モデルで行っているバリデーションを別ディレクトリに分けたいと思い立ちました。

流れ

  1. validatorsディレクトリの作成
  2. validatorクラスの作成・実装
  3. モデルクラスで利用する

実装

1 validatorsディレクトリの作成

appディレクトリ配下にvalidatorsディレクトリを作成します。

app/validators

2 validatorsクラスの作成・実装

validatorsクラスをvalidatorsディレクトリ配下に作成します。

以下、プランモデルの詳細情報の文字数制限をするバリデーションを例にご紹介します。

app/validators/plan_content_length_validator.rb

class PlanContentLengthValidator < ActiveModel::Validator ・・・①
   def validate(plan) ・・・②
      plan.errors.add(:base, '相談詳細は3文字以上書いてください。') if plan.content.size <= 3 ・・・③
   end
end

validatorsクラスはActiveModel::Validatorを継承します。

また、クラス名とファイル名も連動しています。ファイル名をスネークケースで作成し、それに連動した形でキャメルケースでクラス名を作成します。

validateメソッドを定義します。

引数は、モデルクラスから渡されるインスタンスが入ります。

バリデーションを作成し、エラーメッセージを明示的に定義します。

validatorクラスでは、エラーメッセージを明示的に指定する必要があります。

3 モデルクラスで利用する

モデルクラスで作成したvalidatorクラスを利用します。

app/models/plan.rb

validates_with PlanLengthValidator

validates_withメソッドを利用することでvalidatorクラスを利用できます。

上記の通り、validates_withメソッドを利用することでvalidatorクラスにモデルクラスのインスタンスが渡されます。

以上でバリデーションをvalidatorディレクトリに分けることができました。

 

感想

バリデーションを別ディレクトリに分けることで、ファットモデルの原因を1つ潰せるのはいいと思いました。(というか別ディレクトリに分ける主な理由がこれな気がします)

ただ、validatorクラスでエラーメッセージを明示的に定義しなければいけないなど手間になる部分も多いため、必須項目や文字数制限などはvalidateメソッドでモデルクラスに定義してしまった方がわかりやすいかなと思います。

以上!!!!!!!