Monkey patching ActiveResource::Errors

百般思念 提交于 2019-12-23 03:16:14

问题


I've come across an issue with ActiveResource that has been resolved and was trying to monkey patch it into my application without much luck.

I've added a file in config/initializers/ containing the following:

class ActiveResource::Errors < ActiveModel::Errors
    # https://github.com/rails/rails/commit/b09b2a8401c18d1efff21b3919ac280470a6eb8b
    def from_hash(messages, save_cache = false)
      clear unless save_cache

      messages.each do |(key,errors)|
        errors.each do |error|
          if @base.attributes.keys.include?(key)
            add key, error
          elsif key == 'base'
            self[:base] << error
          else
            # reporting an error on an attribute not in attributes
            # format and add themActive  to base
            self[:base] << "#{key.humanize} #{error}"
          end
        end
      end
    end

    # Grabs errors from a json response.
    def from_json(json, save_cache = false)
      decoded = ActiveSupport::JSON.decode(json) || {} rescue {}
      if decoded.kind_of?(Hash) && (decoded.has_key?('errors') || decoded.empty?)
        errors = decoded['errors'] || {}
        if errors.kind_of?(Array)
          # 3.2.1-style with array of strings
          ActiveSupport::Deprecation.warn('Returning errors as an array of strings is deprecated.')
          from_array errors, save_cache
        else
          # 3.2.2+ style
          from_hash errors, save_cache
        end
      else
        # <3.2-style respond_with - lacks 'errors' key
        ActiveSupport::Deprecation.warn('Returning errors as a hash without a root "errors" key is deprecated.')
        from_hash decoded, save_cache
      end
    end
end

But it seems still to be calling activeresource-3.2.2/lib/active_resource/validations.rb:31:in 'from_json'. Any help on how properly to monkey patch this would be very much appreciated.

Thanks!


回答1:


It turns out that the problem was Rails lazy loading ActiveResource after my file was loaded in the config, overriding it with the original definitions. The fix is simply requiring the needed files before defining the patched code.

My revised code:

require 'active_resource/base'
require 'active_resource/validations'

module ActiveResource
  class Errors
    # https://github.com/rails/rails/commit/b09b2a8401c18d1efff21b3919ac280470a6eb8b

    def from_hash(messages, save_cache = false)
      clear unless save_cache

      messages.each do |(key,errors)|
        errors.each do |error|
          if @base.attributes.keys.include?(key)
            add key, error
          elsif key == 'base'
            self[:base] << error
          else
            # reporting an error on an attribute not in attributes
            # format and add themActive  to base
            self[:base] << "#{key.humanize} #{error}"
          end
        end
      end
    end

    # Grabs errors from a json response.
    def from_json(json, save_cache = false)
      decoded = ActiveSupport::JSON.decode(json) || {} rescue {}
      if decoded.kind_of?(Hash) && (decoded.has_key?('errors') || decoded.empty?)
        errors = decoded['errors'] || {}
        if errors.kind_of?(Array)
          # 3.2.1-style with array of strings
          ActiveSupport::Deprecation.warn('Returning errors as an array of strings is deprecated.')
          from_array errors, save_cache
        else
          # 3.2.2+ style
          from_hash errors, save_cache
        end
      else
        # <3.2-style respond_with - lacks 'errors' key
        ActiveSupport::Deprecation.warn('Returning errors as a hash without a root "errors" key is deprecated.')
        from_hash decoded, save_cache
      end
    end
  end
end


来源:https://stackoverflow.com/questions/9677485/monkey-patching-activeresourceerrors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!