Active Record Validations 6 Performing Custom Validations 执行个性化校验

阅读更多

version Rails 4.1

6. 执行个性化校验
当内建的校验辅助方法不能满足你的需求时, 你能够写你自己更喜欢的校验类或者校验方法.
 

6.1 Custom Validators 个性化校验

个性化校验是类(class), 该类继承ActiveModel::Validator. 这些类必须实现一个validate方法, 它会带入一个record作为一个参数, 然后对这个record执行校验. 个性化校验是通过使用 validates_with 方法来被调用的.
class   MyValidator < ActiveModel::Validator
   def   validate(record)
     unless   record.name.starts_with?  'X'
       record.errors[ :name ] <<  'Need a name starting with X please!'
     end
   end
end
 
class   Person
   include ActiveModel::Validations
   validates_with MyValidator
end

对于校验各个属性增加个性化校验最简单的方式是用ActiveModel::EachValidator的规则. 在这个例子中, 个性化校验类必须实现一个validate_each方法, 该方法有三个参数: record, attribute和value, 和实例相对应, 被校验的属性和属性的值都存在于被传入方法的实例中.

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

正如在例子中显示的, 你同样结合标准的校验和你自己个性化的校验.

 

6.2 Custom Methods 个性化方法

你也能够创建方法来校验你模型的状态以及给errors集合增加信息, 当他们是无效的时候. 然后你必须要注册这些方法, 通过使用validate类的方法, 传入标志, 即校验方法名.

 

对于每一个方法你能够传入多于一个的标志, 各自的校验将会在同一个指令中运行, 正如他们被注册时那般.

class   Invoice < ActiveRecord::Base
   validate  :expiration_date_cannot_be_in_the_past ,
     :discount_cannot_be_greater_than_total_value
 
   def   expiration_date_cannot_be_in_the_past
     if   expiration_date.present? && expiration_date < Date.today
       errors.add( :expiration_date ,  "can't be in the past" )
     end
   end
 
   def   discount_cannot_be_greater_than_total_value
     if   discount > total_value
       errors.add( :discount ,  "can't be greater than total value" )
     end
   end
end

默认情况下,  类似的校验在你每次调用valid?时, 将会运行. 同样也能控制, 当去运行这些个性化校验时, 通过给校验的方法后增加一个 :on 选项, 赋值 :create 或者 :update. 

class   Invoice < ActiveRecord::Base
   validate  :active_customer , on:  :create
 
   def   active_customer
     errors.add( :customer_id ,  "is not active" )  unless   customer.active?
   end
end
 
original url:   http://guides.rubyonrails.org/active_record_validations.html#performing-custom-validations

你可能感兴趣的:(rails,ruby,validation)