문제

나는이 문제에 머물러있다.

ActiveSupport::JSON 정의합니다 to_json 다양한 핵심 물체에서 JSON GEM도 마찬가지입니다. 그러나 구현은 동일하지 않습니다. ActiveSupport 버전은 인수를 가져오고 JSON GEM 버전은 그렇지 않습니다.

JSON 보석이 필요한 보석을 설치했고 앱이 파손되었습니다. 문제는 내가 사용하고 있다는 것입니다 to_json 객체 목록을 반환하는 컨트롤러에서 어떤 속성이 반환되는지 제어하고 싶습니다.

내 시스템의 어느 곳에서나 코드가있을 때 require 'json' 이 오류 메시지가 표시됩니다.

TypeError: wrong argument type Hash (expected Data)

나는 그것을 고치기 위해 온라인으로 읽은 몇 가지를 시도했지만 아무것도 효과가 없었습니다. 나는 보석을 다시 작성하여 사용했습니다 ActiveSupport::JSON.decode 대신에 JSON.parse.

이것은 작동하지만 지속 가능하지는 않습니다 ... JSON GEM이 필요한 보석을 사용하고 싶을 때마다 보석을 갈 수 없습니다.

업데이트: 이 문제의 가장 좋은 해결책은 Rails 2.3 이상으로 업그레이드하여 고정하는 것입니다.

도움이 되었습니까?

해결책

업데이트 이 수정은 Rails <2.3에만 적용됩니다. Giles가 아래에서 언급했듯이, 그들은 동일한 기술을 사용하여 내부적으로 2.3에서 이것을 수정했습니다. 그러나 JSON GEM의 Rails 호환성에 대한 초기 시도를 조심하십시오. (json/add/rails), 필요한 경우, 명시 적으로 모든 것을 다시 깨뜨릴 것입니다.

당신은 의미합니까? require 'json' 진술 자체가 그 예외를 제기합니까? 아니면 전화 할 때 의미합니까? @something.to_json(:something => value) 오류가 발생합니까? 후자는 내가 기대할 것입니다. JSON GEM이 필요한 문제가 있다면 무슨 일이 일어나고 있는지 잘 모르겠습니다.

방금 Oauth Gem과 함께이 문제를 해결했습니다. 제 경우에는 진정한 갈등이 없습니다. Oauth 보석은 to_json 구현. 따라서 문제는 JSON이 Actives Support 선언을 작성하고 있다는 것입니다. ActiveSupport가로드되기 전에 JSON을 단순히 요구함으로써 이것을 해결했습니다. 퍼팅

require 'json'

내부 Rails::Initializer 트릭을했지만 (블록 이후에 넣지는 않았지만).

이를 통해 ActiveSupport는 대신 기본 JSON 구현을 클로 브러 할 수 있습니다.

이제 JSON 구현에 실제로 의존하는 보석을 사용하는 경우 to_json 그런 다음 당신은 개울입니다. 이것은 분명히 메타 프로그래밍의 최악이며, 레일과 JSON GEM 개발자가 갈등을 해결하기 위해 옹호 할 것이지만, 하나 또는 다른 하나는 거꾸로 호환되기 때문에 고통 스러울 것입니다.

단기적으로 GEM 저자는 두 구현을 지원함으로써 격차를 해소 할 수 있습니다. 이것은 보석이 방법을 사용하는 방법에 따라 다소 가능합니다. 최악의 시나리오는 공식 포크입니다 (즉. gem 그리고 gem-rails).

다른 팁

업데이트: Rails 3.2에서도 동일한 문제가 해결되지 않은 상태로 남아 있습니다. 불쾌한 해킹은 JSON 보석을 강제로로드하고 덮어 씁니다.

결국 나는 다음 코드로 끝났다. 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 인코딩에 더 빠릅니다. 아마도 당신은 똑같이하고 싶을 것입니다. :)


나는 Rails 2.3.8까지 비슷한 문제를 겪었습니다.

문제는 그 것입니다 ActiveSupport::JSON.backend = 'JSONGem' 반 자격 솔루션이며 여전히 일부 인코더를 직접 덮어 써야합니다. (경고: Multijson을 사용하는 Rails 3.x의 경우 ActiveSupport::JSON.backend = :json_gem 적어도, 또는 조용히 No-Op가 될 것입니다.)

제 경우에는 덮어 쓰야했습니다 String#to_json JSON GEM 1.4.3은 ASCII이지만 Valid-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 무엇이든 문자열, 배열 및 해시.

이것을 잠시 동안 싸운 후 .. 나는 가장 간단한 해결책을 찾았다.

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에서 이것을 고쳤다 고 확신하지만 어떻게 기억할 수 없다.

비록 고유 한 경우에, 나는 Ruby (비-레일) 앱을 가지고 있었는데, 실제로 JSON을 참조하는 일부 보석뿐만 아니라 Rails 앱 (config/Environment.rb Load)을 실제로로드했습니다. 이로 인해 Rails App의 Environment.rb 파일을 단순히 변경할 수 없기 때문에 큰 두통이 발생했습니다. 나는 끔찍한 typeerror : 잘못된 인수 유형 HASH (예상 데이터) 메시지를 올리지 않고 JSON이 작동하도록하기 위해 많은 보석을 포킹하게되었습니다.

나는이 솔루션으로 운이 좋았는데, 위의 커뮤니티 위키의 대답과는 정반대입니다 ...http://blog.swivel.com/code/2009/03/active-support-and-json-gems-dont-play-nice.html기본적으로 옹호하는 사람들에게 'Active_Support'가 필요합니다.전에 'JSON'필요

이것이 내가 작동하게 할 수있는 유일한 방법이었고, 몇 달에 걸쳐 모든 것을 시도했다고 믿습니다.

아직 시도하지는 않았지만 Rails 2.3.3처럼 보입니다.

ActiveSupport::JSON.backend = 'JSONGem'

여기에서 찾았습니다

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top