Сериализация (и десериализация) «сложных» объектов Rails с помощью JSON - PullRequest
2 голосов
/ 13 ноября 2010

Возможно, это глупый вопрос, но я относительно новичок в Rails, и мне интересно, как Rails обрабатывает сериализацию модели, которая имеет has_many (и / или bound_to) объекты другого класса.Будет ли сериализован весь граф объектов по умолчанию?Вы обязательно этого хотите?Вы можете это контролировать?Как?

Есть ли какие-нибудь хитрости на приемном конце относительно того, как десериализовать его?или в значительной степени перебор присваивает свойства их хэш-значениям, и любые встроенные массивы / хэши становятся ассоциированными объектами класса?

Edit : Добавление примера json, возвращенного с использованием примера @ zetetic.Хотите знать, почему встроенные коллекции (кольца) имеют escape-символы (\) перед каждой цитатой (")?

{"name":"Gizmo","height":15,"grommets":"[{\"name\":\"Sid\",\"color\":\"yellow\"},{\"name\":\"Elvis\",\"color\":\"\"},{\"name\":\"Teeny\",\"color\":\"Red\"}

Ответы [ 2 ]

3 голосов
/ 13 ноября 2010

Нет, по умолчанию при сериализации экземпляра модели выдаются только его собственные атрибуты, а не атрибуты его ассоциаций. Но вы можете настроить это поведение, включив в модель метод as_json:

class MyModel < ActiveRecord::Base
  has_many :widgets

  def as_json(options={})
    {
      :name => name,
      :widgets => widgets.to_json
    }
  end
end

Возможно, вы захотите определить as_json и в связанной модели, иначе вы получите стандартный хэш атрибутов.

EDIT

Оказывается, что приведенный выше пример работает только для верхнего уровня, а не для ассоциаций, которые в конечном итоге избежали. Чтобы пример работал, определите as_json с необходимыми атрибутами в Widget, затем в MyModel вызовите as_json для каждого элемента коллекции:

def as_json(options={})
  {
    :name => name,
    :widgets => widgets.map(&:as_json)
  }
end

Полагаю, вместо этого вы можете установить Arkey # as_json, но я предпочитаю использовать map.

EDIT

Если вы думаете о том, чтобы проголосовать против этого ответа, сначала прочитайте этот . Использование :include является предпочтительным подходом.

1 голос
/ 30 декабря 2010

Легко! (проверено на Rails 2.3.8)

из http://apidock.com/rails/ActiveRecord/Serialization/to_json

Чтобы включить ассоциации, используйте: include

    konata.to_json(:include => :posts)
  # => {"id": 1, "name": "Konata Izumi", "age": 16,
        "created_at": "2006/08/01", "awesome": true,
        "posts": [{"id": 1, "author_id": 1, "title": "Welcome to the weblog"},
                  {"id": 2, author_id: 1, "title": "So I was thinking"}]}

Подробнее см. Ссылку выше.

Для меня это даже работало с ассоциациями ": has_many,: through".

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