В рубине:
class Obj
attr_accessor :price
end
my_ruby_obj = Obj.new
ставит my_ruby_obj.to_json
"\"#<Obj:0x1c9b018>\""
Сервер отправляет my_ruby_obj.to_json в браузер (sinatra, с content_type: json) в ответ на запрос jQuery ajax (с $.get), который правильно определяет тип возврата json и запускает функцию обратного вызова (данные), которая:
console.log(data);
который возвращает:
#<Obj:0x1c9b018>
Теперь как мне получить доступ к атрибуту data.price в javascript/jquery, как обычно я делаю на ruby-объекте для доступа к его атрибуту? ( "My_ruby_obj.price")
Я попытался с console.log(data.price);
> Undefined
Я чувствую, что здесь отсутствует большая часть... и я думаю, это связано с тем, как json работает с объектами.
Любая помощь? Если возможно, я ищу правильный способ сделать это с помощью jquery.
благодаря
edit: пытаясь понять, что происходит, я попробовал это в обратном вызове:
newdata = $.parseJSON(data);
но отладка консоли останавливается на нем, показывая:
> uncaught exception: Invalid JSON: #<Obj:0x1c9b018>
Я звонил.to_json на объект ruby, так почему он так говорит?...
[[ new_edit: ]]
Кажется, что сериализация ruby json для объектов из пользовательских классов не работает, как я предполагал:
Цитата: qaru.site/questions/88473/...
Это будет немного сложнее для объектов из ваших собственных классов. Для следующего класса to_json создаст нечто вроде
"\"#<A:0xb76e5728>\""
. Это, вероятно, нежелательно. Чтобы эффективно сериализовать ваш объект как JSON, вы должны создать свой собственный метод to_json.
и примеры следуют... Но.. вау... нет ли более простого способа?
Хорошо, я нашел именно то, что искал ! Автоматическое быстрое решение, которое также поставляется с другими преимуществами (более высокая скорость!).
Стандартный json gem работает только для некоторых классов (Array, Hash,..) и не может перевести пользовательский класс/объект, который вы создали для JSON. Он не знает, как организовать данные, если вы не напишете собственный метод.to_json для своего класса, и это то, что я пытался избежать.
Итак, в конце концов я нашел драгоценный камень под названием Oj: Optimized Json (gem install oj)
Цитируя авторов:
Оптимизированный JSON (Oj), как следует из названия, был написан для обеспечения ускоренной обработки JSON. Он был разработан как более быстрая альтернатива Yajl и другим общим анализаторам Ruby JSON. До сих пор было достигнуто, что примерно в 2 раза быстрее, чем Яджл для синтаксического анализа и в 3 или более раза быстрее написания JSON.
Oj имеет несколько режимов дампа или сериализации, которые управляют тем, как объекты преобразуются в JSON. Эти режимы устанавливаются с опцией: mode в параметрах по умолчанию или в качестве одного из параметров метода dump().
: object mode будет выгружать любой объект как объект JSON с ключами, которые соответствуют именам переменных Ruby Object без символа "@". Это режим максимальной производительности.
Я использовал его так:
json = Oj.dump(guy, mode: :object)
но в моем случае он работал без режима:: object.
теперь console.log(data);
показывает:
({'^o':"Human", x:38, y:58, name:"Jack", bday:{'^t':1352083824.5625}, age:50})
Теперь, когда сериализация работает хорошо, я могу, наконец, сделать следующее:
console.log(data.age);
/ / ---> 50
Сериализация также выполняется быстрее.
Это была длинная поездка, хотя;)
Большое спасибо вам за библиотеку автор: http://twitter.com/#!/peterohler
Вы возвращаете строковое представление своего объекта через javascript, а не объект себя.
Вам нужно вернуть представление JSON для него:
render json: my_ruby_obj.to_json
Или даже лучше, если вы знаете поля, которые вам нужны для доступа:
render json: {price: my_ruby_obj.price}
to_json
доступен в приложении sinatra. Вы просто отправляете простую строку "# <Obj: 0x1c9b018>" - необходимо отправить фактический JSON.