2013-07-26 2 views
7

У меня есть контроллер Rails, который отвечает объектами JSON. Давайте рассмотрим этот теоретический пример:Rails 4 - Пользовательский (json) формат объектов ответа в Rails

respond_to :json 
def index 
    respond_with Comment.all 
end 

Это отвечало бы с чем-то вроде

[{"id":1,"comment_text":"Random text ", "user_id":1 ,"created_at":"2013-07-26T15:08:01.271Z","updated_at":"2013-07-26T15:08:01.271Z"}] 

Что я ищу является «лучшей практикой» способом вмешиваться в форматировании объекта JSon и возврат что-то вроде этого:

[{"id":1,"comment_text":"Random text ", "username": "John Doe", "user_id":1 ,"created_at":"3 hours ago"}] 

Как вы можете видеть, я добавляю столбец, который не существует в модели базы данных «имя пользователя», я везу из «updated_at», и я форматирование " created_at "в содержат человекообразный текст, а не дату.

Любые мысли кто-нибудь?

+0

Лучше всего для JBuilder: https://github.com/rails/jbuilder Он включен в Rails 4 по умолчанию , – germs12

ответ

4

2 пути:

первый: определить вид, где вы строите и возвращает хэш, который вы будете конвертировать в формат JSON.

контроллер:

YourController < ApplicationController 
    respond_to :json 

    def index 
    @comments = Comment.all 
    end 
end 

вид: index.json.erb

res = { 
    :comments => @comments.map do |x| 
    item_attrs = x.attributes 
    item_attrs["username"] = calculate_username 
    end 
} 

res.to_json.html_safe 

второе: использование драгоценных камней active_model_serializers

3

Я бы переопределить as_json метод модели.

В модели Comment,

def username 
    "John Doe" 
end 

def time_ago 
    "3 hours ago" 
end 

def as_json(options={}) 
    super(:methods => [:username, :time_ago], except: [:created_at, :updated_at]) 
end 

Вы не должны изменить ваш контроллер

Посмотрите на документацию для as_json

+0

используйте метод to_json и передайте нужные вам параметры, простые и гибкие. Вы можете легко использовать разные действия для передачи более или менее атрибутов из вашей модели. Все детали приведены в документации, связанной выше –

12

Перезапись as_json или работе с представлениями JSON ERB может быть громоздким, поэтому я предпочитаю использовать сериализаторы ActiveModel (или RABL):

class CommentSerializer < ActiveModel::Serializer 
    include ActionView::Helpers::DateHelper 

    attributes :id, :created_at 

    def created_at 
    time_ago_in_words(object.created_at) 
    end 

end 

Посмотрите здесь для получения дополнительной информации:

  1. https://github.com/rails-api/active_model_serializers
  2. https://github.com/nesquena/rabl