2012-08-09 10 views
5

रेल 2 से रेल तक माइग्रेशन के साथ 3 सत्यापन त्रुटियों को ActiveRecord :: ActiveModel :: त्रुटियों में त्रुटि से स्थानांतरित किया गया था।
सत्यापन त्रुटि 2 पटरियों में एक प्रकार और संदेश (अन्य बातों के अलावा) था और आप की तरह कुछ कर रही द्वारा प्रमाणीकरण त्रुटि के प्रकार की जांच कर सकता है:ActiveModel :: त्रुटियों के सत्यापन प्रकार को कैसे निर्धारित करें

rescue ActiveRecord::RecordInvalid => e 
    e.record.errors.each do |attr, error| 
    if error.type == :foo 
     do_something 
    end 
    end 
end 

लेकिन रेल 3 के साथ यह सब कुछ लगता है लेकिन अवैध विशेषता और संदेश खो गया है। नतीजतन प्रकार निर्धारित करने के लिए एक ही रास्ता त्रुटि संदेश तुलना करने के लिए है: (।? जैसे कि यदि आप जो एक ही संदेश का उपयोग कई सत्यापन है)

rescue ActiveRecord::RecordInvalid => e 
    e.record.errors.each do |attr, error| 
    if error == "foobar" 
     do_something 
    end 
    end 
end 

कौन सा नहीं है सब पर आदर्श।

प्रश्न:
वहाँ रेल 3.0 में एक बेहतर तरीका सत्यापन त्रुटि के प्रकार का निर्धारण करने के लिए है?

+0

संभावित डुप्लिकेट [? परीक्षण करने के लिए कैसे जो मान्यता ActiveRecord में विफल रहा है] (http://stackoverflow.com/questions/4119379/how-to-test-which-: मैं बंदर पैच के साथ समाप्त हो गया गया है सत्यापन-विफल-इन-एक्टिव्रेकॉर्ड) – lulalala

उत्तर

4

अतिरिक्त के लिए जाँच करें?

https://github.com/rails/rails/blob/master/activemodel/lib/active_model/errors.rb#L331

आपको ऐसा करने की अनुमति देता है कि: ActiveModel :: त्रुटियों से संबंधित

record.errors.added?(:field, :error) 
+0

यह चाल करेगा (हालांकि यह केवल सत्यापन संदेशों की तुलना कर रहा है) लेकिन इसे 3.0 तक बैकपोर्ट नहीं किया गया है (जिसे मैंने विशेष रूप से उल्लेख नहीं किया है, मैं प्रश्न अपडेट करूंगा)। – pricey

+0

इस बारे में बुरी बात यह है कि यह अनुवादित पाठ संदेश पर निर्भर करता है। –

1

मैं इसे परीक्षण प्रयोजनों के लिए, लेकिन यह भी एपीआई के लिए न केवल जरूरत है।

module CoreExt 
    module ActiveModel 
    module Errors 
     # When validation on model fails, ActiveModel sets only human readable 
     # messages. This does not allow programmatically identify which 
     # validation rule exactly was violated. 
     # 
     # This module patches {ActiveModel::Errors} to have +details+ property, 
     # that keeps name of violated validators. 
     # 
     # @example 
     # customer.valid? # => false 
     # customer.errors.messages # => { email: ["must be present"] } 
     # customer.errors.details # => { email: { blank: ["must be present"] } } 
     module Details 
     extend ActiveSupport::Concern 

     included do 
      if instance_methods.include?(:details) 
      fail("Can't monkey patch. ActiveModel::Errors already has method #details") 
      end 

      def details 
      @__details ||= Hash.new do |attr_hash, attr_key| 
       attr_hash[attr_key] = Hash.new { |h, k| h[k] = [] } 
      end 
      end 

      def add_with_details(attribute, message = nil, options = {}) 
      error_type = message.is_a?(Symbol) ? message : :invalid 
      normalized_message = normalize_message(attribute, message, options) 
      details[attribute][error_type] << normalized_message 

      add_without_details(attribute, message, options) 
      end 
      alias_method_chain :add, :details 

      def clear_with_details 
      details.clear 
      clear_without_details 
      end 
      alias_method_chain :clear, :details 
     end 
     end 
    end 
    end 
end 

# Apply monkey patches 
::ActiveModel::Errors.send(:include, ::CoreExt::ActiveModel::Errors::Details) 
की
संबंधित मुद्दे