I have a controller returning a json structure like so:
def show
# .......
o_json = deep_object_1_to_json(o)
render :json => o_json
end
private
def deep_object_1_to_json(o)
o.to_json(
:include => {....})
end
Now I need to extend it to return 2 objects. However the obvious solution is giving me problems:
def show
# .......
o1_json = deep_object_1_to_json(o)
o2_json = deep_object_2_to_json(o)
render :json =>
{
:object_1 => o1_json,
:object_2 => o2_json
}
end
This returns a json object with 2 strings of escaped json data!
The deep_object_2_to_json functions already have several layers of nested includes so I would rather not have to refactor these into a single function. Is there a way to make this easily extendable to add more objects in the future without the double escaping problem above?
Thanks for any pointers.
Sounds like you should be constructing something upon which to_json
can easily be called.
The obvious candidate for active record objects is as_json
. This does everything that to_json
does (include the :include
option and so on) except actually turning the object into json. Instead you get back a ruby hash which you can manipulate as you want and then call to_json. For example you could do
render :json => {
:o1 => object1.as_json(:include => :blah),
:o2 => object2.as_json(:include => :blah)
}
Your controller shouldn't be serializing the object as JSON until right before it hands it off to be rendered.
In other words deep_object_1_to_json
should just be deep_object_1
. Then you can package both return values into an array or hash and render the as JSON.
def show
# .......
o1 = deep_object_1(o)
o2 = deep_object_2(o)
render :json =>
{
:object_1 => o1,
:object_2 => o2
}
end
It might be a pain to change it now, but for the future of your system, you really ought to be doing it this way. JSON is just a format for sending objects over the wire or to disk; none of your code should have any references whatsoever to JSON unless it is passing it off to be rendered.
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