RailsのActive Recordで名前空間付きカスタムバリデーターを利用する
はじめに
こんにちは!
フィッツプラスシステム開発部の伊藤です。
今回の記事では、Active Recordで名前空間付きのカスタムバリデーターを定義し、利用する方法について解説します。
中規模〜大規模のRailsアプリケーションでは、名前空間を使ってクラス名の衝突を避けることが多いかと思います。
例えば、Admin::UserなどUserの中でも管理者を表したい際にAdminという名前空間を付けて他のUserクラスと区別します。
フィッツプラスでも2017年からあるRailsアプリケーションを運用しているので、名前空間を用いたクラスの整理を行っております。
特定の名前空間に特化したカスタムバリデーターを定義したく、今回の内容を調べました。
それでは、名前空間つきのカスタムバリデーターを定義して利用するにはどうすればよいか紹介します。
カスタムバリデーターの定義
カスタムバリデーターの定義は難しくありません。
例えば、利用したいカスタムバリデーターはHoge::CustomValidatorとします。
以下のように、ActiveModel::EachValidatorを継承したバリデータークラスを定義します。
module Hoge
class CustomValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
# ...
end
end
end
詳しくはRailsガイドなどをご参照ください。
モデルでのバリデーター指定方法
ここが一番のポイントです。
モデルで名前空間つきのカスタムバリデーターを指定する際は、名前空間をスラッシュ区切りで指定します。
つまり、先ほどの例では'hoge/custom'と指定します。
ハッシュのキーに/が含まれるためクォートする必要があるので注意してください。
実際のコードでは以下のようになります。
class User < ApplicationRecord
validates :hoge, 'hoge/custom': true # `'<namespace>/<validator名>'` と指定する
end
このように記述することで、Hoge::CustomValidator を利用できます。
validatesメソッドのソースコード
最後にvalidatesメソッドでどのようにバリデーターを読み込んでいるのか紹介します。
validatesメソッドはActiveModel::Validations::ClassMethodsに定義されています。
引数から実際に呼び出すバリデータークラスを抽出しているのは以下の箇所です。
上記ではkey.to_s.camelizeした文字列にValidatorを追加したものが呼び出されるバリデータークラスです。
Active Model側に標準で搭載されているバリデーションを使う際も同じ仕組みです。
-
presence: trueの場合、PresenceValidatorクラス
-
format: { with: /\A[a-zA-Z]+\z/}の場合、FormatValidatorクラス
よって、名前空間つきのバリデータークラスを呼び出したい際も同様です。
以下のように:'hoge/custom'をcamelizeすると、Hoge::Customです。
そしてこれにValidatorをつけることでHoge::CustomValidatorクラスになります。
p :'hoge/custom'.to_s.camelize # => "Hoge::Custom"
p "#{:'hoge/custom'.to_s.camelize}Validator" # => "Hoge::CustomValidator"
ちなみに、ソースコードを調べていたところ、名前空間つきのバリデータークラスを指定する方法がvalidatesメソッドのコメントにちゃんと説明されていました。
以上です。
最後までお読みくださりありがとうございました!
Discussion