Добавление виртуального атрибута в вывод json
допустим, у меня есть приложение, которое обрабатывает список задач. В списке есть законченные и незаконченные пункты. Теперь я хочу добавить два виртуальных атрибута к объекту списка; количество готовых и незавершенных элементов в списке. Мне также нужно, чтобы они отображались в выводе json.
У меня есть два метода в моей модели, которая выбирает незаконченное/законченное элементы:
def unfinished_items
self.items.where("status = ?", false)
end
def finished_items
self.items.where("status = ?", true)
end
Итак, как я могу получить количество этих двух методов в моем выводе json?
Я использую рельсы 3.1
7 ответов:
сериализация объектов в Rails имеет два шага:
- первый,
as_json
вызывается для преобразования объекта в упрощенной хэш.- затем,
to_json
оas_json
возвращаемое значение для получения конечной строки JSON.вы вообще хотите оставить
to_json
в одиночку, поэтому все, что вам нужно сделать, это добавить свойas_json
реализация примерно так:def as_json(options = { }) # just in case someone says as_json(nil) and bypasses # our default... super((options || { }).merge({ :methods => [:finished_items, :unfinished_items] })) end
вы также можете сделать это, как это:
def as_json(options = { }) h = super(options) h[:finished] = finished_items h[:unfinished] = unfinished_items h end
если вы хотите использовать разные имена для метода резервного значения.
если вы заботитесь о XML и JSON, посмотрите на
serializable_hash
.
в Rails 4, Вы можете сделать следующее -
render json: @my_object.to_json(:methods => [:finished_items, :unfinished_items])
надеюсь, что это поможет кому-то, кто находится на более поздней / последней версии
еще один способ сделать это-добавить это в свою модель:
def attributes super.merge({'unfinished' => unfinished_items, 'finished' => finished_items}) end
Это также будет автоматически работать для сериализации xml. http://api.rubyonrails.org/classes/ActiveModel/Serialization.html Имейте в виду, однако, вы можете использовать строки для ключей, так как метод не может иметь дело с символами при сортировке ключей в rails 3. Но он не сортируется в rails 4, поэтому больше не должно быть проблем.
просто закройте все ваши данные в один хэш, как
render json: {items: items, finished: finished, unfinished: unfinished}
Я просто подумал, что предоставлю этот ответ для всех, кто, как и я, пытался интегрировать это в существующий as_json блок:
def as_json(options={}) super(:only => [:id, :longitude, :latitude], :include => { :users => {:only => [:id]} } ).merge({:premium => premium?})
просто отлип
.merge({})
в концеsuper()
как Aswin перечисленные выше,
:methods
позволит вам вернуть метод/функцию конкретной модели в качестве атрибута json, если у вас есть сложные ассоциации, это сделает трюк, так как он добавит функции к существующей модели/assossiations :D он будет работать как шарм, если вы не хотите переопределятьas_json
проверить этот код, и, пожалуйста, обратите внимание, как я использую
:methods
а также:include
[N + запрос даже не вариант ;)]
render json: @YOUR_MODEL.to_json(:methods => [:method_1, :method_2], :include => [:company, :surveys, :customer => {:include => [:user]}])
перезаписи
as_json
функция будет намного сложнее в этом сценарии (особенно потому, что вы должны добавить:include
assossiations вручную :/def as_json(options = { }) end