3

有没有办法从自定义验证器中调用标准 Rails 验证器?

我有 OAuth/电子邮件注册/登录的组合,我希望能够在每种身份验证方法上调用某些验证器。validates_uniqueness_of :email例如,如果用户通过电子邮件注册然后调用单个验证器,例如,我希望能够调用validates_with UserValidator

如果没有办法做到这一点,我将使用状态跟踪和一系列:if验证。

4

3 回答 3

1

我相信没有办法从自定义验证器中调用其他验证器,这也可能导致循环依赖,这是危险的。

您必须使用条件验证,但请记住,您可以像这样确定它们的范围(取自 Rails Guides)

with_options if: :is_admin? do |admin|
  admin.validates :password, length: { minimum: 10 }
  admin.validates :email, presence: true
end
于 2013-12-29T15:30:05.377 回答
1

如果您的目标是调用自定义和标准 Rails 验证器的某种组合,您可以validates使用ActiveModel::Validations

例如,您创建了一个自定义Email Validator

class EmailValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    record.errors.add attribute, (options[:message] || "is not an email") unless
      value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
  end
end

你想把它包括在你的Person课堂上。你可以这样做:

class Person < ApplicationRecord
  attr_accessor :email

  validates :email, presence: true, email: true
end

这将调用您的自定义验证器,并且PresenceValidator. 此处所有示例均取自文档ActiveModel::Validations::Validates

于 2018-07-24T03:17:18.440 回答
0

我不确定这是否是 Rails 的最新更改,但在 6.1 中可以从自定义验证器调用标准验证器:

class VintageYearValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    ActiveModel::Validations::NumericalityValidator.new({
      attributes: attributes,
      only_integer: true,
      greater_thank_or_equal_to: 1900,
      less_than_or_equal_to: 2100
    }).validate_each(record, attribute, value)

    # Your custom validation
    errors.add() unless bla?

  end
end

这些标准验证器并没有真正记录在案(https://apidock.com/rails/v6.1.3.1/ActiveModel/Validations/NumericalityValidator),因此使用风险自负。但似乎没有循环依赖的风险。您的自定义验证器和标准验证器都继承自 EachValidator。

于 2021-10-28T00:45:20.860 回答