Controlling the order of rails validations

前端 未结 5 549
天命终不由人
天命终不由人 2020-12-02 22:05

I have a rails model which has 7 numeric attributes filled in by the user via a form.

I need to validate the presence of each of these attributes which is obviously

5条回答
  •  执笔经年
    2020-12-02 23:00

    The James H solution makes the most sense to me. One extra thing to consider however, is that if you have conditions on the dependent validations, they need to be checked also in order for the dependent_attributes_valid? call to work.

    ie.

        validates :attribute1, presence: true
        validates :attribute1, uniqueness: true, if: :attribute1?
        validates :attribute1, numericality: true, unless: Proc.new {|r| r.attribute1.index("@") }
        validates :attribute2, presence: true
        ...
        validates :attribute7, presence: true
    
        validate :calculations_ok?, unless: Proc.new { |a| a.dependent_attributes_valid? }
    
        def dependent_attributes_valid?
          [:attribute1, ..., :attribute7].each do |field|
            self.class.validators_on(field).each do |v|
              # Surely there is a better way with rails?
              existing_error = v.attributes.select{|a| self.errors[a].present? }.present?
    
              if_condition = v.options[:if]
              validation_if_condition_passes = if_condition.blank?
              validation_if_condition_passes ||= if_condition.class == Proc ? if_condition.call(self) : !!self.send(if_condition)
    
              unless_condition = v.options[:unless]
              validation_unless_condition_passes = unless_condition.blank?
              validation_unless_condition_passes ||= unless_condition.class == Proc ? unless_condition.call(self) : !!self.send(unless_condition)
    
              if !existing_error and validation_if_condition_passes and validation_unless_condition_passes
                v.validate(self)
              end
            end
            return false if self.errors.messages[field].present?
          end
          return true
        end
    

提交回复
热议问题