将虚拟属性添加到json输出

假设我有一个处理TODO列表的应用程序。 清单已经完成,未完成的项目。 现在我想添加两个虚拟属性的列表对象; 列表中已完成和未完成项目的计数。 我也需要这些在json输出中显示。

我有两个方法在我的模型中取得未完成/完成的项目:

def unfinished_items self.items.where("status = ?", false) end def finished_items self.items.where("status = ?", true) end 

那么,我怎样才能在我的JSON输出中得到这两个方法的计数呢?

我正在使用Rails 3.1

Rails中对象的序列化有两个步骤:

  • 首先, as_json将对象转换为简化的哈希。
  • 然后,在as_json返回值上调用as_json来获取最终的JSONstring。

你通常想单独离开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请注意,虽然您可能希望使用string的键,因为该方法不能处理符号时,在轨道3sorting键。但它不是sorting在轨道4,所以不应该有问题了。;

把你所有的数据closures到一个散列 ,就像

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()的末尾即可