这个问题把我弄糊涂了。
ActiveSupport::JSON在各种核心对象上定义了to_json,JSON也是如此。但是,实现是不一样的-- ActiveSupport版本使用参数,JSON版本不使用参数。
我安装了一个创业板,它需要JSON,我的应用程序就坏了。问题是,我在一个返回对象列表的控制器中使用to_json,但我希望控制返回哪些属性。
当我的系统中任何地方的代码执行require 'json'时,我都会收到以下错误消息:
TypeError: wrong argument type Hash (expected Data)
我尝试了一些我在网上读到的东西来修复它,但是没有什么效果。最后,我重写了gem,使用ActiveSupport::JSON.decode而不是JSON.parse。
这是可行的,但它是不可持续的.我不能每次我想要使用一个需要JSON宝石的宝石时,我都要分叉宝石。
更新:这个问题的最佳解决方案是升级到Rails 2.3或更高版本,由Rails修复它。
发布于 2009-04-15 19:10:52
更新此修补程序仅适用于Rails < 2.3。正如Giles在下面提到的,他们在2.3内部使用了相同的技术修复了这个问题。但是要注意json早先对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实现。
现在,如果您使用的gem实际上依赖于to_json的JSON实现,那么您将陷入困境。这无疑是元编程中最糟糕的,我主张Rails和JSON创业板开发人员解决冲突,尽管这将是痛苦的,因为其中一个或另一个将不得不破坏向后兼容性。
在短期内,gem作者可能能够通过支持这两种实现来弥补这一差距。这在一定程度上是可行的,取决于gem如何使用该方法。最坏的情况是正式的分叉。gem和gem-rails)。
发布于 2010-07-19 22:23:26
UPDATE:即使使用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行代码使应用程序的JSON编码速度比快50倍。也许你也想这么做。:)
在Rails 2.3.8之前,我一直有类似的问题。
问题是,ActiveSupport::JSON.backend = 'JSONGem'是一个半途而废的解决方案,您仍然需要自己重写一些编码器。(警告:对于使用MultiJson的Rails 3.x,它至少必须是ActiveSupport::JSON.backend = :json_gem,否则它将是没有操作的。)
在我的例子中,我需要覆盖String#to_json,因为JSON 1.4.3更好,因为它不会盲目地编码非ascii-但有效的-UTF8 8字符,在没有必要的情况下,这样就可以得到更短的字节(有利于序列化)和容易读取的结果(在我看来,"日本語"比"\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 - String、Array和Hash。
发布于 2012-09-07 20:16:09
经过一段时间的斗争之后..。我发现最简单的解决办法是:
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在激活端口被装载后,把它放在任何地方。
https://stackoverflow.com/questions/683989
复制相似问题