Как делают Вы имеете дело с конфликтом между ActiveSupport:: JSON и драгоценный камень JSON?

В JavaScript массивы являются экземпляром Object, и их тип будет регистрироваться как таковой.

Оператор наподобие

foo[i] = 'bar'

назначит значение 'bar' в i -ом индексе массива (или объекта), начинающемся с нуля foo. Это происходит в for циклах в коде, который вы разместили.

var a = []

console.log(a instanceof Object)

a[3] = 4

console.log(a)

14
задан 3 revs 20 January 2010 в 18:14
поделиться

5 ответов

Обновление Это исправление применимо только к Rails <2.3. Как Джайлс упоминает ниже, они исправили это в 2.3, используя почти ту же технику. Но будьте осторожны с более ранней попыткой json gem на совместимость с Rails ( json / add / rails ), , которая, если потребуется, явно сломает все заново.

Вы имеете в виду Требование 'json' само по себе вызывает это исключение? Или вы имеете в виду, когда вы вызываете @ кое-что.to_json (: что-то => значение) вы получаете ошибку? Последнее - то, чего я ожидал, если у вас есть проблема, требующая гем JSON, тогда я не уверен, что происходит.

Я только что столкнулся с этой проблемой с гемом oauth. В моем случае, нет истинного конфликта, потому что камень оаут не t зависит от реализации to_json . Следовательно, проблема в том, что JSON блокирует объявления ActiveSupport. Я решил это, просто запросив json перед загрузкой ActiveSupport. Поместив

require 'json'

в Rails :: Initializer , добился цели (хотя поставить его после того, как блок НЕ сделал).

Это позволяет ActiveSupport вместо этого реализовать реализацию JSON по умолчанию.

Теперь, если вы вы используете гем, который на самом деле зависит от JSON-реализации to_json , тогда вы в затруднительном положении. Это определенно худшее из метапрограммирования, и я бы посоветовал разработчикам Rails и JSON-гемов разрешить конфликт, хотя это будет болезненно, потому что одному или другому придется нарушить обратную совместимость.

В краткосрочной перспективе , Авторы драгоценных камней могут преодолеть этот пробел, поддерживая обе реализации. Это более или менее возможно в зависимости от того, как драгоценный камень использует метод. В худшем случае это официальный форк (т.е. gem и gem-rails ).

4
ответ дан 1 December 2019 в 10:19
поделиться

Я почти уверен, что они исправили это в 2.3, но не могу вспомнить, как.

0
ответ дан 1 December 2019 в 10:19
поделиться
-

Я еще предстоит попробовать, но он выглядит как рельсы 2.3.3 дает вам некоторую связь:

ActiveSupport::JSON.backend = 'JSONGem'

Найдено здесь

0
ответ дан 1 December 2019 в 10:19
поделиться

В моем, хотя и уникальном случае, у меня было приложение Ruby (без рельсов), которое фактически загружало приложение Rails (из загрузки config / environment.rb) а также некоторые драгоценные камни, ссылающиеся на json. Это вызвало у меня огромные головные боли из-за того, что я не мог просто изменить файл environment.rb приложения Rails. Я закончил тем, что разветвлял несколько драгоценных камней, чтобы заставить json работать, не вызывая ужасного сообщения TypeError: неправильный тип аргумента Hash (ожидаемые данные).

Мне повезло с этим решением, которое прямо противоположно ответу сообщества вики выше ... http://blog.swivel.com/code/2009/03/active -support-and-json-gems-dont-play-nice.html , который в основном защищает вызов require 'active_support' ДО { {1}} require 'json'

Это был единственный способ заставить его работать, и поверьте мне, я пробовал все на протяжении многих месяцев.

0
ответ дан 1 December 2019 в 10:19
поделиться

ОБНОВЛЕНИЕ : Даже с 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. Наверное, ты хочешь сделать то же самое. :)


У меня была похожая проблема до Rails 2.3.8.

Проблема в том, что ActiveSupport :: JSON.backend = 'JSONGem' - неполноценное решение, и вам все равно нужно перезаписать некоторые кодировщики самостоятельно. ( ПРЕДУПРЕЖДЕНИЕ : для Rails 3.x, который использует MultiJson, он должен быть как минимум ActiveSupport :: JSON.backend =: json_gem , иначе он будет автоматически отключен.)

В моем случае мне пришлось перезаписать String # to_json , потому что гем JSON 1.4.3 лучше тем, что он не кодирует вслепую символы, отличные от ascii-but-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 для чего угодно - String , Массив и хеш.

19
ответ дан 1 December 2019 в 10:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: