Rails カスタム検証を理解する
ある要件を検討し、これらの各々またはいずれかの必要性を理解しましょう。
テーブル名が items
であるアイテム モデルがあり、各レコードが title
, description
,width
, height
, depth
, weight.
各アイテムは次のルールに従います:
- タイトルが最低 10 文字で、それぞれのタイトルにキーワードすなわち、(1) と、 (2) がなければならないことを望みます。
great-article
. - アイテムの体積は20~3000立方メートルでなければならない(つまり、1.0~2.0)。 Volume Validation)
- The compactness of the item cannot exceed 200 grams per cubic meters(ie.
Compactness Validation
) - No side length is less than the largest side (ie. proportion validation)。
さて、最初のルールをピックアップして、最初のアプローチ
- Use a custom method to perform the validation.
私たちはカスタム検証の最初のアプローチ、すなわちモデルクラス内にvalidateメソッドを定義することを使用しました。 可能な限り、ロジックを別のヘルパー クラスに抽出することが望ましいです。
2番目のアプローチ、すなわちヘルパーバリデータクラスを作成することによって、密度を検証してみましょう。 rails が提供する #validates_with
method は、検証をヘルパークラスに向けます。
class Item < ActiveRecord::Base
…
validates_with CompactnessValidator
…
end
ここで、ヘルパークラス CompactnessValidator
/models/concerns ディレクトリに “compactness_validator.rb” を作成する必要があります。 CompactnessValidator
はActiveModel::Validator
を継承しており、#validate
というメソッドがあるのがプロパテントである。 このメソッドはレコード全体にアクセスすることができる。
class CompactnessValidator << ActiveModel::Validator
def validate(record)
if record.compactness > 10
record.errors.add(:compactness, "is too high to safely dispatch")
end
end
end
ここで、この同じクラスでさまざまな属性のバリデーションをn個追加することができることに注意してください。
カスタム検証ヘルパーを作成することで、rails に組み込まれたものと同様に、「item_dimensions_proportion:true」と言うだけで直接使用できます。
class Item < ActiveRecord::Base
...
validates :height, :width, :depth, item_dimensions_proportion: true
...
end
ここで item_dimensions_proportion フラッグを true に設定したため、 rails は ItemDimensionsProportionValidator という検証用のヘルパークラスを持っていると期待するようになりました。 そこで、models concern ディレクトリに “item_dimensions_proportion_validator.rb” というファイルを作成します。
検証を容易にするために #validates_each
メソッドを定義しなければなりません。
カスタム バリデータを使用することは、コードに関連する検証を別のクラスに抽出したい場合に最適です。 モデルのすべてのバリデーションコードが1つの場所にあるので、デバッグにも本当に便利です。 また、複数のクラスで同じバリデーターを使用することもできるので、本当に便利で素晴らしいです。
あなたのアプリケーションでこれらのカスタム バリデーターを試してみて、これが良い方法で役に立ったかどうか教えてください。 また、何か問題があれば、[email protected] までご連絡ください。
読者を増やしたいので、このブログが役に立つと感じたら、友人や同僚などと共有していただけるようお願いします。
ありがとうございます。