Luk*_*ncl 14 ruby json ruby-on-rails activesupport
我很难过这个问题.
ActiveSupport::JSON定义to_json了各种核心对象,JSON gem也是如此.但是,实现方式并不相同 - ActiveSupport版本接受参数而JSON gem版本不接受参数.
我安装了一个需要JSON gem的gem,我的应用程序坏了.问题是我to_json在一个返回对象列表的控制器中使用,但我想控制返回哪些属性.
当我的系统中的任何地方的代码,我require 'json'收到此错误消息:
TypeError: wrong argument type Hash (expected Data)
我尝试了一些我在网上阅读的东西来修复它,但没有任何效果.我最终重新编写了宝石ActiveSupport::JSON.decode而不是使用JSON.parse.
这可行,但它不可持续......每次我想要使用需要JSON gem的gem时,我都不能分享宝石.
更新:此问题的最佳解决方案是升级到Rails 2.3或更高版本,修复它.
ken*_*enn 19
更新:即使使用Rails 3.2,同样的问题仍未解决.令人讨厌的黑客强行加载json gem并覆盖它,就是这样.
最终我得到了以下代码,完全绕过了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
Run Code Online (Sandbox Code Playgroud)
8行代码使您的应用程序的JSON编码速度提高了50倍.也许你想做同样的事情.:)
直到Rails 2.3.8,我一直遇到类似的问题.
问题是这ActiveSupport::JSON.backend = 'JSONGem'是一个半解决方案,你仍然需要自己覆盖一些编码器.(警告:对于使用MultiJson的Rails 3.x,它必须ActiveSupport::JSON.backend = :json_gem至少,否则它将是静默无操作.)
在我的情况下,我需要覆盖,String#to_json因为JSON gem 1.4.3更好,因为它不会以"\uXXXX"不必要的形式盲目编码非ascii-but-valid-UTF8字符,所以你得到更短的字节(好)对于序列化)和易于阅读的结果("???"看起来比我的眼睛更性感"\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
Run Code Online (Sandbox Code Playgroud)
并且你可以随意使用to_json任何东西 - String,Array和Hash.
更新 此修复仅适用于 Rails < 2.3。正如 Giles 在下面提到的,他们在 2.3 中使用几乎相同的技术在内部修复了这个问题。但要注意 json gem 之前对 Rails 兼容性的尝试( json/add/rails),如果明确需要的话,这将再次破坏一切。
您的意思是require 'json'语句本身引发了该异常吗?或者你的意思是当你打电话时@something.to_json(:something => value)你会得到错误?后者是我所期望的,如果您遇到需要 JSON gem 的问题,那么我不确定发生了什么。
我刚刚遇到了 oauth gem 的这个问题。就我而言,不存在真正的冲突,因为 oauth gem 不依赖于to_json实现。因此,问题在于 JSON 破坏了 ActiveSupport 声明。我通过在加载 ActiveSupport 之前简单地要求 json 来解决这个问题。推杆
require 'json'
Run Code Online (Sandbox Code Playgroud)
在里面Rails::Initializer做到了这一点(尽管把它放在块后面却没有)。
这允许 ActiveSupport 破坏默认的 JSON 实现。
现在,如果您使用的 gem 实际上依赖于 JSON 实现to_json那么您就陷入困境了。这绝对是最糟糕的元编程,我建议 Rails 和 JSON gem 开发人员解决冲突,尽管这将是痛苦的,因为其中之一将不得不破坏向后兼容性。
从短期来看,gem 作者也许能够通过支持这两种实现来弥补差距。这或多或少可行取决于宝石如何使用该方法。最坏的情况是官方分叉(即gem和gem-rails)。
| 归档时间: |
|
| 查看次数: |
16094 次 |
| 最近记录: |