使用相同的验证器对不同的属性Rails



我有一个自定义验证器,我想将其应用于同一模型中的多个属性

现在我下面的工作很好:

validates :first_name, validator_name: true
validates :age, validator_name: true
validates :gender, validator_name: true

但当我尝试:

validates :first_name, :age, :gender, validator_name: true

验证器将运行第一个属性(:first_name),但不运行其他属性。这有可能实现吗?我花了几个小时在谷歌上搜索,但没有找到任何例子

module Person
class SomeValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
return unless can_do_something?(record, attribute)
#... more code 
end
def can_do_something?(record, attribute)
anything_new = record.new_record? || record.attribute_changed?(attribute)
end
end
end

不确定这是否应该只是一个评论或如果它构成一个答案;然而你所要求的…

我有一个自定义验证器,我想将其应用于同一模型中的多个属性

…是EachValidator的工作原理

所以你所描述的…

验证器将运行第一个属性(:first_name),但不运行其他属性。

. .不准确。

例如:

require 'active_model'
class StartsWithXValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
unless value.match?(/^(?:d+s|^)X/)
record.errors.add attribute, "must start with X"
end
end
end
class Person
include ActiveModel::Model
include ActiveModel::Validations

attr_accessor :name, :city, :street

validates :name, :city, :street, starts_with_x: true
end

在本例中,所有三个属性都将通过StartsWithXValidator进行验证。

person = Person.new({name: 'Xavier', city: 'Xenia', street: '123 Xenial St'})
person.valid? 
#=> true
person_2 = Person.new({name: 'Benjamin', city: 'Philadelphia', street: '700 Market St'})
person_2.valid? 
#=> false
person_2.errors.full_messages 
#=> ["Name must start with X", "City must start with X", "Street must start with X"]

工作示例

我认为你可以使用自定义方法验证:

validate :validate_person
def validate_person
[:first_name, :age, :gender].each do |attr|
validates attr, validator_name: true
end
end

参考:https://guides.rubyonrails.org/active_record_validations.html自定义方法

相关内容

  • 没有找到相关文章

最新更新