Добавление виртуального атрибута в вывод 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функция будет намного сложнее в этом сценарии (особенно потому, что вы должны добавить:includeassossiations вручную :/def as_json(options = { }) end