Декодирование JSON в рельсах простой строкой вызывает ошибку - PullRequest
12 голосов
/ 27 мая 2011

Я пытаюсь кодировать / декодировать простые строки в json, но получаю ошибку.

в рельсах 2.3. w / ruby ​​1.8.6, раньше работал.

>> puts ActiveSupport::JSON.decode("abc".to_json)
abc
=> nil

В рельсах 3.1beta1 с ruby ​​1.9.2 возникает ошибка.

ruby-1.9.2-p180 :001 > puts ActiveSupport::JSON.decode("abc".to_json)
MultiJson::DecodeError: 706: unexpected token at '"abc"'
    from /home/stevenh/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/json/common.rb:147:in `parse'
    from /home/stevenh/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/json/common.rb:147:in `parse'
    from /home/stevenh/.rvm/gems/ruby-1.9.2-p180/gems/multi_json-1.0.1/lib/multi_json/engines/json_gem.rb:13:in `decode'
    [...]

Это почти тот же вопрос, который обсуждался на nil.to_json не может быть проанализирован обратно на nil?

Но в 2.3 / 1.8.7 также работал ноль.

puts ActiveSupport::JSON.decode(nil.to_json)
nil

Это новый нормальный?

Ответы [ 3 ]

8 голосов
/ 08 июля 2011

Это изменение произошло при переключении с бэкэнда JSON ActiveSupport на MultiJson , который был включен в Rails 3.1.0.rc1.Согласно команде MultiJson текущее поведение является правильным, а предыдущая реализация была ошибочной из-за спецификации RFC4627 грамматики JSON:

2.  JSON Grammar

   A JSON text is a sequence of tokens.  The set of tokens includes six
   structural characters, strings, numbers, and three literal names.

   A JSON text is a serialized object or array.

      JSON-text = object / array

Asни "abc", ни "/"abc/"" не являются сериализованными объектами или массивами, ошибка при попытке их декодирования уместна.

Диаграммы с сайта JSON усиливают эту спецификацию.

Как говорится, это может означать ошибку в реализации to_json, которая приводит к:

ruby-1.9.2-p180 :001 > "abc".to_json
 => "\"abc\""
1 голос
/ 08 июля 2011

Да, то, что происходит в Rails3, является новым нормальным.Изменения, которые вы иллюстрируете, кажутся отражением зрелой структуры.

Ожидается, что методы с именами «закодировать» и «декодировать» будут полностью соответствовать спецификации JSON , и наоборотдругой.

String # to_json, с другой стороны, это метод с поведенческим подходом, который используется для удобства создания более сложных объектов JSON, предположительно используемых внутри (в ActiveSupport), когда Array # to_json или Hash # to_jsonвстретить строковое значение как один из составляющих их элементов.

0 голосов
/ 29 сентября 2012

Если вам нужно восстановить это поведение, выполните эти шаги , т.е.

# in your Gemfile
gem 'yajl-ruby'

# in your application.rb
require 'yajl/json_gem'

После этих шагов:

Loading development environment (Rails 3.2.8)
[1] pry(main)> puts ActiveSupport::JSON.decode("abc".to_json)
abc
=> nil
[2] pry(main)> puts ActiveSupport::JSON.decode(nil.to_json)

=> nil
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...