Rails as_json issue - Как эффективно включить вложенные объекты?
У меня возникает проблема, когда я работаю с методом as_json и как эффективно возвращать объект в JSON. И он принадлежит объекту как JSON, а объект принадлежит этому объекту принадлежит свой object_to. Код, вероятно, объяснит это лучше.
Нерабочий путь
Класс предупреждения
class Alert < ActiveRecord::Base
belongs_to :message
# for json rendering
def as_json(options={})
super(:include => :message)
end
end
Класс сообщений
def as_json(options={})
super( methods: [:timestamp, :num_photos, :first_photo_url, :tag_names],
include: { camera: { only: [:id, :name] },
position: { only: [:id, :name, :address, :default_threat_level ]},
images: { only: [:id, :photo_url, :is_hidden]} })
end
Проблема с этой первой настройкой заключается в том, что когда у меня есть объект Alert и вызывается
alert.as_json()
Я получаю все атрибуты из Alert и всех атрибутов из Message, но ни один из других атрибутов из сообщения, которое я хочу, например Camera, Position и т.д.
Здесь "Это работает, но, вероятно, не правильный путь дизайна"
Класс предупреждения
class Alert < ActiveRecord::Base
belongs_to :message
# for json rendering
def as_json(options={})
super().merge(:message => message.as_json)
end
end
Класс сообщений
# for json rendering
def as_json(options={})
super( methods: [:timestamp, :num_photos, :first_photo_url, :tag_names])
.merge(:camera => camera.as_json)
.merge(:position => position.as_json)
.merge(:images => images.as_json)
end
В этой 2-й настройке я получаю все вложенные атрибуты сообщений, как я хочу.
Мой вопрос: я пропустил какую-то Rails-конвенцию, чтобы сделать это правильно? Похоже, что было бы/должно быть проще.
Ответы
Ответ 1
Какую версию Rails вы используете? Это известная ошибка в старых версиях Rails, предположительно фиксированная с помощью этого запроса на перенос. Ваш синтаксис подходит ко мне, поэтому, возможно, это ваша проблема?
Кроме того, вы можете также проверить новый active_model_serializers от Jose Valim (основной элемент Rails). Это может по крайней мере дать вам возможность более эффективно обходить вашу проблему.
Ответ 2
Лучший ответ для меня - использование serializable_hash
. @kikito коснулся этого в своем комментарии, но была опечатка, которая помешала ему работать. Это не serialized_hash
, it serializable_hash
.
Буквально просто найдите + замените as_json
на serializable_hash
, и эта ошибка исчезнет. (Он до сих пор не исправлен в Rails 4.0.2). Вы также получаете преимущество в том, что вам легче выполнять API XML позже (некоторые люди все еще используют их!).
Ответ 3
Я бы порекомендовал вам взглянуть на RABL (означает Ruby API Builder Language) gem (railscast, github). Он предлагает вам DSL для определения структуры вашего ответа JSON (а также XML) в шаблонах (например, Haml или CoffeeScript). Он также поддерживает частичные операции.