ToB企服应用市场:ToB评测及商务社交产业平台

标题: [ruby on rails]ActiveModel源码阅读(Validations) [打印本页]

作者: 知者何南    时间: 昨天 08:21
标题: [ruby on rails]ActiveModel源码阅读(Validations)
Validations


  1. class Invoice < ApplicationRecord
  2. validate :active_customer, on: :create
  3. def active_customer
  4.    errors.add(:customer_id, "is not active") unless customer.active?
  5. end
  6. end
复制代码
  1. class Person < ApplicationRecord
  2.   validates :name, presence: true #校验器是PresenceValidator
  3. end
  4. #校验器PresenceValidator
  5. class PresenceValidator < ActiveModel::EachValidator
  6.   def validate_each(record, attribute, value)
  7.     record.errors.add attribute, "can't be blank" if value.blank?
  8.   end
  9. end
复制代码
  1. class Person < ApplicationRecord
  2.   validates_each :name, :surname do |record, attr, value|
  3.     record.errors.add(attr, 'must start with upper case') if value =~ /\A[[:lower:]]/
  4.   end
  5. end
复制代码
  1. class GoodnessValidator < ActiveModel::Validator
  2.   def validate(record)
  3.           # options = { :fields => [:first_name, :last_name] }
  4.           # options = { :abc => [:first_name, :last_name] }
  5.     if options[:fields].any?{|field| record.send(field) == "Evil" }
  6.       record.errors[:base] << "This person is evil"
  7.     end
  8.   end
  9. end
  10. class Person < ApplicationRecord
  11.         #fields是options哈希的一个key,也可以是别的例如 abc: [:first_name, :last_name]
  12.   validates_with GoodnessValidator, fields: [:first_name, :last_name]
  13. end
复制代码
履历:牢记 validate 发生在 save 之前,如果你喜欢用 before_save 之类的举行查验,记得加上 return false 或者改变习惯,用 validate :validate_method 雷同写法举行校验。
Validator


  1. class MyValidator < ActiveModel::Validator
  2.   def validate(record)
  3.     unless record.name.starts_with? 'X'
  4.       record.errors[:name] << 'Need a name starting with X please!'
  5.     end
  6.   end
  7. end
  8. class Person
  9.   include ActiveModel::Validations
  10.   validates_with MyValidator
  11. end
复制代码
  1. class EmailValidator < ActiveModel::EachValidator
  2.   def validate_each(record, attribute, value)
  3.     unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
  4.       record.errors[attribute] << (options[:message] || "is not an email")
  5.     end
  6.   end
  7. end
  8. class Person < ApplicationRecord
  9.   # presence: true为内置的验证类,email: true为自定义的验证类,可以同时使用
  10.   # email: true 对应的验证类必须是EmailValidator, title:true 对应的验证类必须是TitlelValidator
  11.   validates :email, presence: true, email: true
  12. end
复制代码

  1. class Invoice < ApplicationRecord
  2.   validate :expiration_date_cannot_be_in_the_past,
  3.     :discount_cannot_be_greater_than_total_value
  4.   def expiration_date_cannot_be_in_the_past
  5.     if expiration_date.present? && expiration_date < Date.today
  6.       errors.add(:expiration_date, "can't be in the past")
  7.     end
  8.   end
  9.   def discount_cannot_be_greater_than_total_value
  10.     if discount > total_value
  11.       errors.add(:discount, "can't be greater than total value")
  12.     end
  13.   end
  14. end
复制代码

Concern实现

  1. # app/models/concerns/custom_validatable.rb
  2. module CustomValidatable
  3.   extend ActiveSupport::Concern
  4.   included do
  5.     validate :custom_validate
  6.   end
  7.   def validate_custom_fields(fields)
  8.     CustomValidation.order(:position).each do |validation|
  9.       regex = Regexp.new(validation.regex)
  10.       fields.each do |field|
  11.         value = send(field)
  12.         unless value.match?(regex)
  13.           errors.add(field, validation.error_message)
  14.         end
  15.       end
  16.     end
  17.   end
  18. end
复制代码
  1. # app/models/issue.rb
  2. include CustomValidatable
  3. def custom_validate
  4.   validate_custom_fields(['subject', 'description'])
  5. end
复制代码
validates_with实现

  1. class WxMsgSecValidator < ActiveModel::Validator
  2.   # scene: 1 scene_profile 资料, 2 scene_comment 评论, 3 scene_post 论坛, 4 scene_log 社交日志
  3.   def validate(record)
  4.     if options[:fields].select { |field| record.send("#{field}_changed?") }.present?
  5.       case record.class.name
  6.       when 'YouKe'
  7.         @you_ke = record
  8.       else
  9.         @you_ke = record.you_ke
  10.       end
  11.       scene_hash = { desc: 2, content: 2 }
  12.       @you_ke = YouKe.where(is_robot: false).first if @you_ke&.is_robot?
  13.       open_id = @you_ke&.klly? ? @you_ke&.open_id : @you_ke&.wmh_open_id
  14.       return record.errors[:base] << '账号openid不存在' if open_id.nil?
  15.       options[:fields].select { |field| record.send("#{field}_changed?") }.each do |field|
  16.         if record.send(field).present?
  17.           is_deny = @you_ke.klly? ? !Weixin.msg_check(scene_hash[field], open_id, record.send(field)) : !WmhWeixin.msg_check(scene_hash[field], open_id, record.send(field))
  18.           record.errors.add(:base, '输入涉嫌违规') if is_deny
  19.         end
  20.       end
  21.     end
  22.   end
  23. end
复制代码
  1. # app/models/issue.rb
  2. include ActiveModel::Validations
  3. validates_with WxMsgSecValidator, fields: %i[content]
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4