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