ruby on rails - रेल सत्यापन के आदेश को नियंत्रित करना




ruby-on-rails ruby-on-rails-3 (3)

थोड़ी अधिक जटिल स्थितियों के लिए एक विकल्प एक सहायक विधि बनाना होगा जो पहले निर्भर गुणों के लिए मान्यताओं को चलाता है। फिर आप अपना बना सकते हैं: calculations_ok? सत्यापन सशर्त रूप से चलाया।

validates :attribute1, :presence => true
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 { |v| v.validate(self) }
    return false if self.errors.messages[field].present?
  end
  return true
end

मुझे इस परियोजना के लिए ऐसा कुछ बनाना पड़ा क्योंकि आश्रित विशेषताओं पर सत्यापन काफी जटिल थे। मेरा समकक्ष: गणना_ोक? यदि निर्भर गुण सही ढंग से मान्य नहीं होते हैं तो अपवाद फेंक देगा।

लाभ:

  • अपेक्षाकृत डीआरवाई, विशेष रूप से यदि आपके सत्यापन जटिल हैं
  • यह सुनिश्चित करता है कि आपकी त्रुटियों की सरणी मैक्रो-सत्यापन के बजाय सही विफल सत्यापन की रिपोर्ट करती है
  • आपके द्वारा बाद में जोड़े गए आश्रित विशेषताओं पर स्वचालित रूप से कोई अतिरिक्त सत्यापन शामिल होता है

चेतावनियां:

  • संभावित रूप से दो बार सभी मान्यताओं को चलाता है
  • हो सकता है कि आप सभी मान्यताओं को निर्भर गुणों पर चलाना न चाहें

मेरे पास एक रेल मॉडल है जिसमें उपयोगकर्ता द्वारा एक फॉर्म के माध्यम से 7 संख्यात्मक गुण हैं।

मुझे इन विशेषताओं में से प्रत्येक की उपस्थिति को सत्यापित करने की आवश्यकता है जो स्पष्ट रूप से उपयोग करना आसान है

validates :attribute1, :presence => true
validates :attribute2, :presence => true
# and so on through the attributes

हालांकि मुझे एक कस्टम सत्यापनकर्ता चलाने की भी आवश्यकता है जो कई विशेषताओं को लेता है और उनके साथ कुछ गणना करता है। यदि इन गणनाओं का परिणाम किसी निश्चित सीमा के भीतर नहीं है तो मॉडल को अमान्य घोषित किया जाना चाहिए।

अपने आप पर, यह भी आसान है

validate :calculations_ok?

def calculations_ok?
  errors[:base] << "Not within required range" unless within_required_range?
end

def within_required_range?
  # check the calculations and return true or false here
end

हालांकि समस्या यह है कि विधि "मान्य" विधि हमेशा "मान्य" विधि से पहले चला जाती है। इसका अर्थ यह है कि यदि उपयोगकर्ता आवश्यक फ़ील्ड में से एक को खाली छोड़ देता है, तो रेल रिक्त विशेषता के साथ गणना करने का प्रयास करते समय एक त्रुटि फेंकता है।

तो मैं पहले सभी आवश्यक विशेषताओं की उपस्थिति कैसे देख सकता हूं?


मुझे यकीन नहीं है कि यह गारंटी है कि इन मान्यताओं को किस क्रम में चलाया जा सकता है, क्योंकि यह इस बात पर निर्भर हो सकता है कि attributes स्वयं को आदेश दिया है। यदि आप आवश्यक डेटा में से कुछ गायब हैं तो आप अपनी validate विधि को और अधिक लचीला बनाने से बेहतर हो सकते हैं और बस नहीं चल सकते हैं। उदाहरण के लिए:

def within_required_range?
  return if ([ a, b, c, d ].find(&:blank?))

  # ...
end

यह जमानत देगा यदि d माध्यम से कोई भी चर रिक्त है, जिसमें शून्य, खाली सरणी या तार शामिल हैं, और आगे भी।


जेम्स एच समाधान मुझे सबसे ज्यादा समझ में आता है। हालांकि, विचार करने के लिए एक अतिरिक्त बात यह है कि यदि आपके पास निर्भर मान्यताओं पर स्थितियां हैं, तो उन्हें dependent_attributes_valid के लिए भी जांच की आवश्यकता है? काम करने के लिए बुलाओ।

अर्थात।

    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




activemodel