Filter a model's attributes before outputting as json

纵然是瞬间 提交于 2020-01-21 12:25:29

问题


Hey guys, I need to output my model as json and everything is going fine. However, some of the attributes need to be 'beautified' by filtering them through some helper methods, such as number_to_human_size. How would I go about doing this?

In other words, say that I have an attribute named bytes and I want to pass it through number_to_human_size and have that result be output to json.

I would also like to 'trim' what gets output as json if that's possible, since I only need some of the attributes. Is this possible? Can someone please give me an example? I would really appreciate it.

Preliminary search results hint at something regarding as_json, but I can't find a tangible example pertaining to my situation. If this is really the solution, I would really appreciate an example.

Research: It seems I can use to_json's options to explicitly state which attributes I want, but I'm still in need of figuring out how to 'beautify' or 'filter' certain attributes by passing them through a helper before they're output as json.

Would I create a partial for a single json model, so _model.json.erb, and then create another one for the action I'm using, and within that simply render the partial with the collection of objects? Seems like a bunch of hoops to jump through. I'm wondering if there's a more direct/raw way of altering the json representation of a model.


回答1:


Your model can override the as_json method, which Rails uses when rendering 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

Now you can call render :json in the controller:

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

Rails will call Item.as_json for each member of @items and return a JSON-encoded array.




回答2:


I figured out a solution to this problem, but I don't know if it's the best. I would appreciate insight.

@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

Basically I construct a hash on the fly with the values I want and then render that instead. It's working, but like I said, I'm not sure if it's the best way.



来源:https://stackoverflow.com/questions/4550925/filter-a-models-attributes-before-outputting-as-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!