1

Rails の問題に出くわしたので、モデルの検証に使用したいと思います。しかし、検証を一般的なものにして、関心のあるクラスに属性がある場合にのみ検証が使用されるようにします。簡単だと思いましたが、column_names、constantize、send などを使用するなど、多くの方法を試しましたが、何も機能しません。それを行う正しい方法は何ですか?コード:

module CommonValidator
  extend ActiveSupport::Concern

  included do
    validates :email, presence: { message: I18n.t(:"validations.commons.email_missing") }, 
                      format: { with: /\A[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\z/i, 
                      message: I18n.t(:"validations.commons.email_wrong_format"), 
                            allow_blank: true } if self.column_names.include? :email
  end
end

class Restaurant < ActiveRecord::Base
  include CommonValidator
  .
  .
  .
end

もちろん、レストランには電子メール属性があります。私の懸念が含まれているクラスに属性が存在するかどうかを確認することはできますか? 電子メール属性を持たない多くのモデルに CommonValidations を含めたいです。Rails4を使用しています。

4

2 に答える 2

1

respond_to?現在のインスタンスで次のように使用できます。

validates :email, presence: { message: I18n.t(:"validations.commons.email_missing") }, 
                  format: { with: /\A[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\z/i, 
                  message: I18n.t(:"validations.commons.email_wrong_format"), 
                  allow_blank: true }, 
                  if: lambda { |o| o.respond_to?(:email) }

@coreyward によって提案された別のオプションは、拡張するクラスを定義することEachValidatorです。たとえば、電子メールの検証の場合:

# app/validators/email_validator.rb
class EmailValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    unless value =~ /\A[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\z/i
      record.errors[attribute] << (options[:message] || I18n.t(:"validations.commons.email_wrong_format"))
    end
  end
end

次に、検証呼び出しを次のように更新できます。

validates :email, 
          presence: { message: I18n.t(:"validations.commons.email_missing") },
          email: true, 
          allow_blank: true
于 2014-03-31T20:11:52.803 に答える