首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何处理ActiveSupport::JSON和JSON之间的冲突?

如何处理ActiveSupport::JSON和JSON之间的冲突?
EN

Stack Overflow用户
提问于 2009-03-25 23:51:45
回答 6查看 16.9K关注 0票数 16

这个问题把我弄糊涂了。

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修复它。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 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来解决这个问题。推送

代码语言:javascript
复制
require 'json'

Rails::Initializer内部完成了这个技巧(尽管在块后面放置它没有)。

这使得ActiveSupport可以关闭默认的JSON实现。

现在,如果您使用的gem实际上依赖于to_json的JSON实现,那么您将陷入困境。这无疑是元编程中最糟糕的,我主张Rails和JSON创业板开发人员解决冲突,尽管这将是痛苦的,因为其中一个或另一个将不得不破坏向后兼容性。

在短期内,gem作者可能能够通过支持这两种实现来弥补这一差距。这在一定程度上是可行的,取决于gem如何使用该方法。最坏的情况是正式的分叉。gemgem-rails)。

票数 4
EN

Stack Overflow用户

发布于 2010-07-19 22:23:26

UPDATE:即使使用Rails 3.2,相同的问题仍然没有得到解决。强行加载json创业板并覆盖它的讨厌的黑客攻击,也就是说。

最后,我得到了下面的代码,完全绕过ActiveSupport的to_json。将其放入config/initializers/patches.rb中,就可以执行{}.jsonize[].jsonize来生成JSON字符串。没有任何冲突,保证。

代码语言:javascript
复制
# 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

代码语言:javascript
复制
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。

票数 21
EN

Stack Overflow用户

发布于 2012-09-07 20:16:09

经过一段时间的斗争之后..。我发现最简单的解决办法是:

代码语言:javascript
复制
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

在激活端口被装载后,把它放在任何地方。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/683989

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档