问题
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