I have a Rails Controller who responds with JSON objects. Let's take this theoretical example :
respond_to :json
def index
respond_with Comment.all
end
This would respond with something like
[{"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"}]
What i'm looking for is a "best practice" method to interfere with the formating of the json object and return something like this :
[{"id":1,"comment_text":"Random text ", "username": "John Doe", "user_id":1 ,"created_at":"3 hours ago"}]
As you can see, i'm adding a column that doesn't exist in the database model "username" , i'm taking out "updated_at" , and i'm formatting "created_at" to contain human readable text rather than a date.
Any thoughts anyone ?
Overwriting as_json
or working with JSON ERB views can be cumbersome, that's why I prefer using ActiveModel Serializers (or 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
Look here for more information:
2 ways:
first: define a view, where you build and return an hash that you'll convert to json.
controller:
YourController < ApplicationController
respond_to :json
def index
@comments = Comment.all
end
end
view: index.json.erb
res = {
:comments => @comments.map do |x|
item_attrs = x.attributes
item_attrs["username"] = calculate_username
end
}
res.to_json.html_safe
second: use gem active_model_serializers
I'd redefine the as_json
method of your model.
In your Comment model,
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
You don't have to change your controller
Take a look at the documentation for as_json
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With