如何在rails 5中使用ActiveModel::EachValidator

问题描述 投票:0回答:3

如何使用

ActiveModel::EachValidator
验证特定属性。 我写了下面的代码片段。此验证不会调用保存或验证对象。

class EmailValidator < ActiveModel::EachValidator
    def validate_each(record,attribute,value)
       # Logic to check email is valid or not
    end
end

这适用于 Rails 3。

ruby-on-rails ruby-on-rails-5.1
3个回答
3
投票

您可以将您的

EmailValidator
类放入
models/concerns
目录中。然后在您的模型中,您可以使用下面的示例验证电子邮件属性。

 class User < ApplicationRecord
   validates :email, presence: true, email: true
 end

Rails 遇到

EmailValidator
时会在范围内查找
email: true
类,然后使用
validate_each
方法验证属性。


1
投票

一个简单的基类,可以与 ActiveModel::Validations::ClassMethods#validates_with 一起使用

class User
  include ActiveModel::Validations
  validates_with EmailValidator
end

class EmailValidator < ActiveModel::Validator
  def validate(record)
     # Logic to check email is valid or not
     record.errors.add :email, "This is some complex validation"
  end
end

任何继承自 ActiveModel::Validator 的类都必须实现一个名为 validate 的方法,该方法接受记录。

要导致验证错误,您必须直接从验证器消息中添加到记录的错误。

欲了解更多详情,您可以查看这里

如果您只需要电子邮件验证,那么您可以尝试这个。

class EmailValidator < ActiveModel::EachValidator
  def validate_each(record, attr_name, value)
    unless value =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
      record.errors.add(attr_name, :email, options.merge(:value => value))
    end
  end
end

0
投票

在搜索模型外部定义的自定义验证器时偶然发现了这个问题,其中使用它们需要指定命名空间(如果您需要在其他模型中重用此验证器)。

想象一下以下文件夹结构

| models
  - user.rb
  | validators
    - email_validator.rb

email_validator.rb
的内容是

class Validators::EmailValidator < ActiveModel::EachValidator
    def validate_each(record,attribute,value)
       # Logic to check email is valid or not
    end
end

然后在您的

User
模型(或任何其他模型)中,您必须指定名称空间才能使用它。

class User < ApplicationRecord
  # ...
  validates :email, presence: true, 'validators/email': true
end
© www.soinside.com 2019 - 2024. All rights reserved.