Providing JSON in the controller

I read the book and in the chapter on controllers, when I talked about things, for JSON she has an example similar to this, but without going into details, so I could not figure out the enlarged picture, which fits in this example:

render :json => @projects, :include => tasks 

And also an example of using JSONP with callback functions:

 render :json => @record, :callback => 'updateRecordDisplay' 

Can someone explain this?

+67
json ruby-on-rails
Feb 12 '13 at 2:35 am
source share
3 answers

You usually return JSON either because:

A) You create part / all of your application as a single-page application (SPA), and you need your client-side JavaScript to be able to retrieve additional data without completely reloading the page.

or

B) You create an API that third parties will consume, and you decide to use JSON to serialize your data.

Or maybe you eat your own dogfood and do as

In both cases, render :json => some_data will provide the JSON-ify provided data. The :callback key in the second example needs a more detailed explanation (see below), but this is another variation in the same idea (returning data in such a way that JavaScript can easily handle it.)

Why :callback ?

JSONP (second example) is a way around the Same Origin Policy , which is part of every browser’s built-in security. If you have an API in api.yoursite.com and you will postpone your application from services.yoursite.com , your JavaScript will not (by default) be able to make XMLHttpRequest (XHR - aka ajax) requests from services to api . The way people made their way around this restriction (before the specification was completed

instead, the server will send back:

 valueOfCallbackHere({"name": "John", "age": 45}) 

Thus, the client JS application could create a script tag pointing to api.yoursite.com/your/endpoint?name=John , and have a function valueOfCallbackHere (which must be defined on the client side of the JS) called with data from this other origin.)

+90
Feb 12 '13 at 2:53
source share

What exactly do you want to know? ActiveRecord has methods that serialize entries in JSON. For example, open the rails console and enter ModelName.all.to_json and you will see the JSON output. render :json essentially calls to_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 for use. Alternatively, you can use the callback option to specify the name of the callback you want to call through JSONP.

For example, let's 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:

 class UsersController < ApplicationController def show @user = User.find(params[:id]) render json: @user end end 

Now, if we call an AJAX call using jQuery as follows:

 $.ajax({ type: "GET", url: "/users/5", dataType: "json", success: function(data){ alert(data.name) // Will alert Max } }); 

As you can see, we managed to get User with id 5 from our rails application and use it in our JavaScript code, because it was returned as a JSON object. The callback option simply calls the JavaScript function named named, passed with the JSON object, as the first and only argument.

To give an example callback parameter, look at the following:

 class UsersController < ApplicationController def show @user = User.find(params[:id]) render json: @user, callback: "testFunction" end end 

Now we can request a JSONP request as follows:

 function testFunction(data) { alert(data.name); // Will alert Max }; var script = document.createElement("script"); script.src = "/users/5"; document.getElementsByTagName("head")[0].appendChild(script); 

The motivation for using this callback is usually to bypass browser protection, which restricts cross-resource sharing (CORS). However, JSONP is no longer used because there are other methods to bypass CORS that are more secure and easier.

+48
Feb 12 '13 at 2:53
source share

For instance

 render :json => @projects, :include => :tasks 

You state that you want to render @projects as JSON and include the tasks association in the Project model in the exported information.

For instance

 render :json => @projects, :callback => 'updateRecordDisplay' 

You state that you want to display @projects as JSON and wrap this data in a javascript call that will look something like this:

 updateRecordDisplay({'projects' => []}) 

This allows you to send data to the parent window and bypass the fake problems between sites.

+10
Feb 12 '13 at 2:52
source share



All Articles