Validator
校验可以简单分为 3 个层次:1)完全使用原生的;2)使用原生的 + 带条件判断,或自行设置 errors;3)自定义校验器
自定义校验器,有两种方式:继承于 Validator 或 EachValidator.
继承于 Validator
校验器在整个项目生命周期中只初始化一次。它针对的是整个对象,并且自动执行。这种方式,由 validates_with
加校验器名字的方式进行调用。
任何继承于 ActiveModel::Validator 的校验器都要实现 validate
方法,此方法接收要校验的 record 做为参数。然后,通过 validates_with
方法可以使用刚才定义的校验器。
class MyValidator < ActiveModel::Validator
# 继承于 Validator,需要实现 validate
def validate(record)
record # => The person instance being validated
options # => Any non-standard options passed to validates_with
end
end
class Person
include ActiveModel::Validations
# 调用方式
validates_with MyValidator
end
继承于 EachValidator
实际上,推荐使用这种方式。这种方式,由 validates
以参数的方式进行调用。
任何继承于 ActiveModel::EachValidator 的校验器都要实现 validate_each
方法,此方法接收要校验的 record、attribute、value 做为参数。
class TitleValidator < ActiveModel::EachValidator
# 继承于 EachValidator,需要实现 validate_each
def validate_each(record, attribute, value)
record.errors.add attribute, 'must be Mr., or Mrs.' unless %w(Mr. Mrs.).include?(value)
end
end
然后,通过 validates
方法(刚才定义的校验器做为参数之一)可以使用刚才定义的校验。
class Person
include ActiveModel::Validations
attr_accessor :name
# 调用方式
validates :name, title: true
end
语法糖:
ActiveRecord::Base.class_eval do
def self.validates_date_of(*attr_names)
validates_with TitleValidator, _merge_attributes(attr_names)
end
end
class Person < ActiveRecord::Base
# ...
# 调用方式
validates_title_of :name
end
Note: EachValidator 也继承于 Validator. 但 Rails 所有所有对外提供的校验器,都继承于 EachValidator.
最后更新于
这有帮助吗?