7

我有一个使用 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"}]

如您所见,我正在添加数据库模型“username”中不存在的列,我正在取出“updated_at”,并且我正在格式化“created_at”以包含人类可读的文本而不是日期.

有什么想法吗?

4

3 回答 3

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
于 2013-07-30T15:29:20.887 回答
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

第二:使用 gem active_model_serializers

于 2013-07-26T16:47:33.183 回答
3

我会重新定义as_json你的模型的方法。

在您的评论模型中,

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的文档

于 2013-07-26T16:53:12.627 回答