Activesupport / Multi json: “Did not recognize your adapter specification”

会有一股神秘感。 提交于 2019-12-13 04:24:20

问题


I have a Ruby 1.9.3 / Rails 3.1 project with the following in the gemfile:

gem 'rails', '3.1.12'
gem 'json'
gem 'multi_json', '1.7.7'

That version of rails sets activesupport to 3.1.12 as well. I'm not sure what the exact cause of the problem is, but when running bundle exec rake test, I got the error:

/home/user/.gem/ruby/1.9.3/gems/multi_json-1.7.7/lib/multi_json.rb:121:in 'rescue in load_adapter': Did not recognize your adapter specification. (ArgumentError)
...
(more stack trace, including activesupport methods)

Fortunately I found a solution! See below.


回答1:


Edit: My original answer is outdated and incorrect; read it if you please, but please read the updated information at the bottom.

After viewing a ton of other questions such as these ones:

OmniAuth Login With Twitter - "Did not recognize your adapter specification." Error
Capistrano deploy: "Did not recognize your adapter specification" during assets:precompile
https://github.com/intridea/multi_json/issues/132

I hadn't found a solution, so I dove into the library and determined that load_adapter was receiving the parameter "JSONGem". The alias was failing, and the method attempted to load

/home/user/.gem/ruby/1.9.3/gems/multi_json-1.7.7/lib/multi_json/adapters/JSONGem.rb

This file doesn't exist, but .../json_gem.rb does exist! So I modified load adapter as follows:

def load_adapter(new_adapter)
    # puts "new_adapter: #{new_adapter}"                              # Debugging
    # puts "new_adapater.class: #{new_adapter.class}"                 # Debugging
    case new_adapter
    when String, Symbol
      new_adapter = ALIASES.fetch(new_adapter.to_s, new_adapter)
      new_adapter = "json_gem" if new_adapter =~ /^jsongem$/i         # I added this line
      # puts "final adapter: #{new_adapter}"                          # debugging
      require "multi_json/adapters/#{new_adapter}"
      klass_name = new_adapter.to_s.split('_').map(&:capitalize) * ''
      MultiJson::Adapters.const_get(klass_name)
    when NilClass, FalseClass
      load_adapter default_adapter
    when Class, Module
      new_adapter
    else
      raise NameError
    end
  rescue NameError, ::LoadError
   raise ArgumentError, 'Did not recognize your adapter specification.'
  end

This fixed the problem for me. It's probably not an optimal solution (ideally I would understand WHY the ALIASES.fetch failed, if that is indeed what happened, and fix that), but if your problem is similar then hopefully this quick fix can help.


Update

It's not viable for deployability reasons to modify someone else's gem. Fortunately I found the root cause of the problem. In project_root/config/initializers/security_patches.rb, we had the line

 ActiveSupport::JSON.backend = "JSONGem"

This was the recommended fix to a security bug in older versions of rails. Now that we are on a newer version of rails (i.e, > 3.0), we can simply replace "JSONGem" with "json_gem" (which is what my original modification was doing, in a roundabout way) and not worry about the security issue.



来源:https://stackoverflow.com/questions/27380667/activesupport-multi-json-did-not-recognize-your-adapter-specification

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