你如何处理的ActiveSupport :: JSON和JSON宝石之间的矛盾?
-
22-08-2019 - |
题
我难倒这个问题。
ActiveSupport::JSON
定义各种核心对象to_json
也是如此的JSON宝石。但是,执行不一样的 - 的ActiveSupport版本需要的参数和JSON宝石版没有
我安装了所需的JSON宝石宝石和我的应用程序打破。问题是,我使用to_json
在返回的对象列表的控制器,但我想控制哪些属性返回。
当代码在我的系统中的任何地方并require 'json'
我收到此错误信息:
TypeError: wrong argument type Hash (expected Data)
我试了几件事情,我读在线修复它,但毫无效果。我结束了重新编写的宝石,而不是使用ActiveSupport::JSON.decode
JSON.parse
。
这工作,但它是不可持续的......我想使用需要的JSON宝石宝石每次我不能分叉宝石。
<强>更新:强>此问题的最佳解决方案是升级到滑轨2.3或更高,其固定它
解决方案
<强>更新强> 此修复程序是仅适用于滑轨<2.3。正如下面贾尔斯提到,它们固定在此2.3内部使用大致相同的技术。但要注意在Rails的兼容性的(json/add/rails
)的,如果需要明确将从头再来打破一切。的
你的意思是require 'json'
语句本身引发该异常?或者你的意思是,当你调用@something.to_json(:something => value)
你的错误?后者是我所期望的,如果你有需要的JSON宝石,然后我不知道发生了什么问题。
我只是碰到了这个问题与OAuth的宝石。就我而言,没有一个真正的冲突,因为OAuth的宝石不依赖于to_json
实施。因此,问题是,JSON是重挫了的ActiveSupport声明。我通过加载的ActiveSupport之前简单地要求JSON解决了这个。把
require 'json'
内的Rails::Initializer
确实起作用(虽然把它的块没有后)。
这允许的ActiveSupport到揍默认JSON实现来代替。
现在,如果你使用的是实际上依赖于JSON实施to_json
的宝石,那么你是一个小溪。这绝对是最糟糕的元编程,我会主张对Rails和JSON宝石开发商来解决冲突,虽然这将是痛苦的,因为一方或另一方则要打破向后兼容性。
在短期内,gem作者可能能够通过支持两种实现缩小差距。这或多或少是可行取决于创业板如何使用的方法。最坏的情况下是一个官方叉(即gem
和gem-rails
)。
其他提示
<强>更新强>:即使使用Rails 3.2,同样的问题仍然未定影。讨厌的劈强行加载JSON宝石和覆盖它,这是。
最后我结束了用下面的代码,完全完全绕过的ActiveSupport的to_json
。把它放在config/initializers/patches.rb
,你可以做{}.jsonize
或[].jsonize
产生JSON字符串。没有与任何冲突,保证。
# Undo the effect of 'active_support/core_ext/object/to_json'
require 'json'
[Object, Array, Hash].each do |klass|
klass.class_eval <<-RUBY, __FILE__, __LINE__
def jsonize(options = nil)
::JSON.generate self, :quirks_mode => true
end
RUBY
end
在8行的代码使你的应用程序的 50次强>更快JSON编码。也许你想这样做。 :)
我已经有类似的问题,直到滑轨2.3.8。
问题是,ActiveSupport::JSON.backend = 'JSONGem'
是一个半称职的解决方案,你仍然需要自己重写一些编码器。 (警告强>:为Rails 3.x的,它使用MultiJson,它必须至少ActiveSupport::JSON.backend = :json_gem
,或将是静默无操作)
在我的情况,我需要覆盖String#to_json
因为JSON宝石1.4.3是它不盲目地编码非ASCII-但化有效UTF8字符"\uXXXX"
的形式,它是没有必要的更好,所以你变短字节(好序列化)和易于阅读的结果("日本語"
看起来比"\u65e5\u672c\u8a9e"
多性感到我的眼睛)。
下面就是我一直在使用猴补丁 - 把下面的代码在config/initializers/patches.rb
module ActiveSupport
module JSON
module Encoding
class << self
def escape(string)
::JSON.generate([string])[1..-2]
end
end
end
end
end
和您可以自由使用任何东西to_json
- 字符串数组和Hash
对抗这一段时间后..我发现的最简单的解决方案是:
if defined?(ActiveSupport::JSON)
[Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].each do |klass|
klass.class_eval do
def to_json(*args)
super(args)
end
def as_json(*args)
super(args)
end
end
end
end
端起的ActiveSupport被加载后的任意位置..
我敢肯定,他们在2.3修复了这个,但我不记得如何。
在我尽管独特情况下,我有实际装载一个Rails应用程序(从一个配置/ environment.rb中负载)一个Ruby(非导轨)的应用程序,以及一些宝石所引用JSON。这引起了我巨大的头痛由于这样的事实,我不能简单地改变Rails应用程序的environment.rb文件中。 最后我为了得到JSON不提高可怕的TypeError工作分叉一些宝石:错误的参数类型哈希(预期数据)消息
我有一些运气使用此解决方案,这是完全相反如上社区维基的答案... 的http:// blog.swivel.com/code/2009/03/active-support-and-json-gems-dont-play-nice.html 这基本上主张调用 需要“active_support” BEFORE 要求 'JSON'
这是我能使其发挥作用的唯一途径,相信我,我试过了很多个月的一切。