カスタムバリデーター
[カスタムバリデーター]とは?
モデルに記載するのとは別で、自分でバリデーションメソッドを作成することができる
[app/validators]を作成することで自動で読み込んでくれる
EachValidatorメソッド
[EachValidator]メソッドは、1つの属性に対しての検証を定義できる
[EachValidator]メソッドは、以下の3つを引数として受け取れる
・record: モデルのインスタンス
・attribute: 属性名
・value: 属性値
クラス名は、[検証名]Validatorの形式にする必要がある
以下に使用例を記述します
[app/models/site.rb] class Site < ApplicationRecord validates :og_image, attachment: { purge: true, content_type: %r{\Aimage/(png|jpeg)\Z}, maximum: 524_288_000 } # [app/validators/attachment_validator.rb]に定義したattachment validates :favicon, attachment: { purge: true, content_type: %r{\Aimage/png\Z}, maximum: 524_288_000 } validates :main_images, attachment: { purge: true, content_type: %r{\Aimage/(png|jpeg)\Z}, maximum: 524_288_000 } end
[app/validators/attachment_validator.rb] class AttachmentValidator < ActiveModel::EachValidator include ActiveSupport::NumberHelper def validate_each(record, attribute, value) return if value.blank? || !value.attached? has_error = false if options[:maximum] if value.is_a?(ActiveStorage::Attached::Many) # 画像が複数枚投稿された場合 value.each do |v| unless validate_maximum(record, attribute, v) has_error = true break end end else # 画像が1枚投稿された場合 has_error = true unless validate_maximum(record, attribute, value) end end if options[:content_type] if value.is_a?(ActiveStorage::Attached::Many) # 画像が複数枚投稿された場合 value.each do |v| unless validate_content_type(record, attribute, v) has_error = true break end end else # 画像が1枚投稿された場合 has_error = true unless validate_content_type(record, attribute, value) end end record.send(attribute).purge if options[:purge] && has_error end private def validate_maximum(record, attribute, value) if value.byte_size > options[:maximum] record.errors[attribute] << (options[:message] || "は#{number_to_human_size(options[:maximum])}以下にしてください") false else true end end def validate_content_type(record, attribute, value) if value.content_type.match?(options[:content_type]) true else record.errors[attribute] << (options[:message] || 'は対応できないファイル形式です') false end end end
上記でoptions[:maximum]は、バリデーションに定義したmaximumの値を参照できる(デバッグで確認した以下を参照)
[1] pry(#<AttachmentValidator>)> options[:maximum] => 524288000 [2] pry(#<AttachmentValidator>)> options[:content_type] => /\Aimage\/(png|jpeg)\Z/ [3] pry(#<AttachmentValidator>)> options[:purge] => true