2010-04-23 3 views
1

Кто-нибудь будет любезен, чтобы рассеять слияние! метод? Его использование условий и присваивание переменных выглядит довольно кратким, и я испытываю трудное время после него. Хотелось бы услышать, что разработчик, занимающийся разработкой Ruby, разлучает это.Разбивка этого рубинового кода?

module ActiveRecord 
    class Errors 

    def merge!(errors, options={}) 
     fields_to_merge = if only=options[:only] 
     only 
     elsif except=options[:except] 
     except = [except] unless except.is_a?(Array) 
     except.map!(&:to_sym) 
     errors.entries.map(&:first).select do |field| 
      !except.include?(field.to_sym) 
     end 
     else 
     errors.entries.map(&:first) 
     end 
     fields_to_merge = [fields_to_merge] unless fields_to_merge.is_a?(Array) 
     fields_to_merge.map!(&:to_sym) 

     errors.entries.each do |field, msg| 
     add field, msg if fields_to_merge.include?(field.to_sym) 
     end 
    end 
    end 
end 
+0

Там довольно много здесь происходит. Если вы зададите более конкретный вопрос, будет легче ответить. –

ответ

7
module ActiveRecord 
    class Errors 

    def merge!(errors, options={}) 


     # This method has two major sections. 

     # 1. Figure out which fields we want to merge, based on the options. 

     # First check to see if we're supposed to whitelist or blacklist 
     # any fields. 
     # fields_to_merge is simple being assigned the return value of 
     # the if/elsif/else block. 
     # 
     fields_to_merge = if only=options[:only] 
     # Whitelist 
     # Implies that options[:only] looks like :only => :foo, but that 
     # seems short-sighted and should probably be refactored to work 
     # like the blacklist, complete with to_sym conversions. 
     only 

     elsif except=options[:except] 
     # Blacklist 
     # You can pass in a single field or an array. 
     # :except => [:foo, :bar, :yourmom] or :except => :foo 
     # In the latter case, this is about to be converted to [:foo] so that 
     # it's an array either way. 
     except = [except] unless except.is_a?(Array) 

     # For each array element, convert that element to a symbol. 
     # "foo" becomes :foo 
     # This is a short hand for "map" which is equivalent to the following: 
     # except.map!{|field| field.to_sym} 
     except.map!(&:to_sym) 

     # The "entries" method comes from Enumerable and works like to_a. 
     # In the case of a hash, you end up with an array of arrays. 
     # Assuming there are already errors, the output of that will look 
     # something like: 
     # [['user', 'can't be blank'], ['some_other_field', 'has problems']] 
     # 
     # Mapping this to :first means "send the 'first' message to each array 
     # element. Since the elements are themselves arrays, you end up 
     # with ['user', 'some_other_field'] 
     # 
     # Now we do a 'select' on that array, looking for any field names that 
     # aren't in our 'except' array. 
     errors.entries.map(&:first).select do |field| 
      !except.include?(field.to_sym) 
     end 
     else 
     # No filters. Just dump out an array of all field names. 
     errors.entries.map(&:first) 
     end 

     # Make sure that we have an array, which at this point is only possible 
     # if we're using an :only => :foo. 
     fields_to_merge = [fields_to_merge] unless fields_to_merge.is_a?(Array) 

     # Make sure that they are all symbols (again with the :only, see the 
     # note above about refactoring). 
     fields_to_merge.map!(&:to_sym) 


     # 2. Now we know what fields we care about, yank in any errors with a 
     # matching field name from the errors object. 

     errors.entries.each do |field, msg| 
     # 'add' is a method on ActiveRecord::Errors that adds a new error 
     # message for the given attribute (field). 
     # In this case, any error from the errors object passed into this 
     # method with a field name that appears in the 'fields_to_merge' 
     # array is added to the existing errors object. 
     # 
     add field, msg if fields_to_merge.include?(field.to_sym) 
     end 
    end 
    end 
end 
Смежные вопросы