I was reading a book and in a chapter about Controllers when it talks about rendering stuff, for JSON it has an example like this but doesn't go in to details so I couldn't figure out the bigger picture that this example fits in:
render :json => @projects, :include => tasks
And also some example with JSONP using it with callback functions:
render :json => @record, :callback => 'updateRecordDisplay'
Can someone explain these?
What exactly do you want to know? ActiveRecord has methods that serialize records into JSON. For instance, open up your rails console and enter
ModelName.all.to_json
and you will see JSON output.render :json
essentially callsto_json
and returns the result to the browser with the correct headers. This is useful for AJAX calls in JavaScript where you want to return JavaScript objects to use. Additionally, you can use thecallback
option to specify the name of the callback you would like to call via JSONP.For instance, lets say we have a
User
model that looks like this:{name: 'Max', email:' m@m.com'}
We also have a controller that looks like this:
Now, if we do an AJAX call using jQuery like this:
As you can see, we managed to get the User with id 5 from our rails app and use it in our JavaScript code because it was returned as a JSON object. The callback option just calls a JavaScript function of the named passed with the JSON object as the first and only argument.
To give an example of the
callback
option, take a look at the following:Now we can crate a JSONP request as follows:
The motivation for using such a callback is typically to circumvent the browser protections that limit cross origin resource sharing (CORS). JSONP isn't used that much anymore, however, because other techniques exist for circumventing CORS that are safer and easier.
You'll normally be returning JSON either because:
A) You are building part / all of your application as a Single Page Application (SPA) and you need your client-side JavaScript to be able to pull in additional data without fully reloading the page.
or
B) You are building an API that third parties will be consuming and you have decided to use JSON to serialize your data.
Or, possibly, you are eating your own dogfood and doing both
In both cases
render :json => some_data
will JSON-ify the provided data. The:callback
key in the second example needs a bit more explaining (see below), but it is another variation on the same idea (returning data in a way that JavaScript can easily handle.)Why
:callback
?JSONP (the second example) is a way of getting around the Same Origin Policy that is part of every browser's built-in security. If you have your API at
api.yoursite.com
and you will be serving your application off ofservices.yoursite.com
your JavaScript will not (by default) be able to makeXMLHttpRequest
(XHR - aka ajax) requests fromservices
toapi
. The way people have been sneaking around that limitation (before the Cross-Origin Resource Sharing spec was finalized) is by sending the JSON data over from the server as if it was JavaScript instead of JSON). Thus, rather than sending back:the server instead would send back:
Thus, a client-side JS application could create a
script
tag pointing atapi.yoursite.com/your/endpoint?name=John
and have thevalueOfCallbackHere
function (which would have to be defined in the client-side JS) called with the data from this other origin.)For the instance of
You are stating that you want to render
@projects
as JSON, and include the associationtasks
on the Project model in the exported data.For the instance of
You are stating that you want to render
@projects
as JSON, and wrap that data in a javascript call that will render somewhat like:This allows the data to be sent to the parent window and bypass cross-site forgery issues.