在输出为json之前过滤模型的属性

时间:2010-12-29 01:50:32

标签: ruby-on-rails json html-helper

嘿伙计们,我需要输出我的模型作为json,一切都很顺利。但是,某些属性需要通过一些辅助方法(例如number_to_human_size)进行过滤来“美化”。我该怎么做呢?

换句话说,假设我有一个名为bytes的属性,我希望将其传递给number_to_human_size并将 结果输出到json。

如果可能的话,我还想'修剪'输出为json的输出,因为我只需要一些属性。这可能吗?有人可以举个例子吗?我真的很感激。

初步搜索结果提示有关as_json的内容,但我无法找到与我的情况有关的实际例子。如果这真的是解决方案,我真的很感激一个例子。

研究:我似乎可以使用to_json选项明确说明我想要的属性,但我仍然需要弄清楚如何'美化'或'通过在将它们输出为json之前将它们传递给助手来过滤'某些属性。

我会为单个json模型创建一个部分,所以_model.json.erb,然后为我正在使用的动作创建另一个,并在其中简单地使用对象集合渲染部分?看起来像一堆箍跳过。我想知道是否有更直接/原始的方式来改变模型的json表示。

2 个答案:

答案 0 :(得分:7)

您的模型可以覆盖Rails在渲染json时使用的as_json方法:

# class.rb
include ActionView::Helpers::NumberHelper
class Item < ActiveRecord::Base
  def as_json(options={})
    { :state => state, # just use the attribute when no helper is needed
      :downloaded => number_to_human_size(downloaded)
    }
  end
end

现在您可以在控制器中调用render :json

@items = Item.all
# ... etc ...
format.json { render :json => @items }

Rails会为@items的每个成员调用Item.as_json并返回一个JSON编码的数组。

答案 1 :(得分:1)

我想出了 解决这个问题的方法,但我不知道它是否是最好的。我很感激洞察力。

@items = Item.all

@response = []

@items.each do |item|
  @response << {
      :state => item.state,
      :lock_status => item.lock_status,
      :downloaded => ActionController::Base.helpers.number_to_human_size(item.downloaded),
      :uploaded => ActionController::Base.helpers.number_to_human_size(item.uploaded),
      :percent_complete => item.percent_complete,
      :down_rate => ActionController::Base.helpers.number_to_human_size(item.down_rate),
      :up_rate => ActionController::Base.helpers.number_to_human_size(item.up_rate),
      :eta => item.eta
  }
end

respond_to do |format|
  format.json { render :json => @response }
end

基本上我使用我想要的值动态构造哈希,然后渲染 。它工作正常,但就像我说的那样,我不确定这是不是最好的方式。