Reputation: 52510
The standard mechanism I return JSON in a Rails controller is with:
respond_to do |format|
format.html
format.json { render json: @cars }
end
Is there a way to modify the @cars
JSON? In particular I simply want to add 4 extra fields in there.
UPDATE: Sorry, I should've explained a little more. @cars
contains a list of Car
objects. I want to add 4 fields to each Car
object in the JSON. This is unique to a particular controller, so I don't want to make an as_json
method as that would affect other JSONs of this class.
Upvotes: 3
Views: 5297
Reputation: 1213
You can also add custom or nested fields with something like:
class MyModel < ActiveRecord::Base
def as_json(options)
super(options).merge({
"custom" => "myvalue",
:name => self.name.titleize,
"result" => self.my_method(self.value1)
})
end
end
Upvotes: 3
Reputation: 6786
If you want to edit the json then you can use ActiveSupport::JSON.decode
to decode the json. It will give you an array of hash which is easily modifiable and then you can convert that to json using to_sosn
Example: I have used rails console to demonstrate. You need the last portion only.
>> cars = [{id: 1,name: 'foo'}, {id:2, name: 'bar'}]
[{:id=>1, :name=>"foo"}, {:id=>2, :name=>"bar"}]
>> json = cars.to_json
"[{\"id\":1,\"name\":\"foo\"},{\"id\":2,\"name\":\"bar\"}]"
>> parsed_json = ActiveSupport::JSON.decode json
[{"id"=>1, "name"=>"foo"}, {"id"=>2, "name"=>"bar"}]
Then you can iterate that array and modify where necessary and convert back to json
Upvotes: 0
Reputation: 11689
If you have to do it once, you should use to_json
( http://apidock.com/rails/ActiveRecord/Serialization/to_json ) in this way, directly in your controller:
@object.to_json(:except => ['created_at', 'updated_at'], :methods => ['method1', 'method2'])
In :methods
you can specify additional methods you want include.
activemodel_serializer should be used only if you do it very often (for example on a JSON API), if you do it only once in your project, you shouldn't do it.
You can also use the default Rails 4 builder if you are actually using Rails 4.
Notice that the most famous gem for building JSON is RABL, but I do prefer activemodel_serializer. There is also a very nice railscasts available for free about it.
Upvotes: 2
Reputation: 754
I think it could use a method to do the adding fields process and render the return result. Could the following work for you:
In a helper
def some_method(in_param, from_which_controller)
return_array = Array.new
obj_array = JSON.parse(in_param);
obj_array.each do |obj|
case from_which_controller
when from_controller_a
# add the field to obj or some other thing
when ...........
# add the field to obj or some other thing
end
return_array << obj # or new obj instead of obj
end
return return_array.to_json
end
In your controller:
respond_to do |format|
format.html
format.json { render json: some_method(@cars, this_controller) }
end
Upvotes: 0
Reputation: 1551
There are two ways that you can modify the structure of the json returned.
Override the #as_json method on the model
model Car < ActiveRecord::Base
def as_json(options={})
opts = {
:only => [:id, :name],
:methods => [:custom_method]
}
super(options.merge(opts))
end
def custom_method
# some extra info (possibly calculated values)
end
end
You can use the active_model_serializer gem. This is my preferred method because it comes with a few built-in conveniences.
class CarSerializer < ActiveModel::Serializer
attributes :id, :name, :custom_method
def custom_method
# method only available within serializer
end
end
Upvotes: 2