Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return 2 json objects at once?

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.

like image 211
Chris Avatar asked Jan 17 '23 06:01

Chris


2 Answers

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)
}
like image 193
Frederick Cheung Avatar answered Jan 18 '23 20:01

Frederick Cheung


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.

like image 26
benzado Avatar answered Jan 18 '23 19:01

benzado