有没有办法从自定义验证器中调用标准 Rails 验证器?
我有 OAuth/电子邮件注册/登录的组合,我希望能够在每种身份验证方法上调用某些验证器。validates_uniqueness_of :email
例如,如果用户通过电子邮件注册然后调用单个验证器,例如,我希望能够调用validates_with UserValidator
。
如果没有办法做到这一点,我将使用状态跟踪和一系列:if
验证。
有没有办法从自定义验证器中调用标准 Rails 验证器?
我有 OAuth/电子邮件注册/登录的组合,我希望能够在每种身份验证方法上调用某些验证器。validates_uniqueness_of :email
例如,如果用户通过电子邮件注册然后调用单个验证器,例如,我希望能够调用validates_with UserValidator
。
如果没有办法做到这一点,我将使用状态跟踪和一系列:if
验证。
我相信没有办法从自定义验证器中调用其他验证器,这也可能导致循环依赖,这是危险的。
您必须使用条件验证,但请记住,您可以像这样确定它们的范围(取自 Rails Guides)
with_options if: :is_admin? do |admin|
admin.validates :password, length: { minimum: 10 }
admin.validates :email, presence: true
end
如果您的目标是调用自定义和标准 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
我不确定这是否是 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。