Why do controllers need multiple format renderings? - ruby-on-rails

Please explain why do we need this code in a controller? What is the significance of this block of code?
respond_to do |format|
format.html # index.html.erb
format.json { render json: #users }
end

It allows you to format output differently depending on the format the user/caller requests. If you were to access http://yourhost/controller/index.html, the controller would respond with the ERB template index.html.erb (or HAML or whatever). If you were to access http://yourhost/controller/index.json, it would respond with the JSON template index.json.erb.
This allows you to have a single controller action that can prepare data and then select the view for rendering based on the requested format.

Defines mime types that are rendered by default when invoking respond_with.
So basically, this means that your controller action can be hit in different formats(html, json in your case), and still provide data back to whatever is calling it. This is helpful for API development, and many other things.
For example: You want to get a json list of all your users to do something with javascript. You'd call /users.json and this would go to your user_controller#index action and know to render a json object of all your users.

The above code is scaffold generated, and provides a way to render *.html and *.json views for your controller, making it easy to have access to data for implementing an API or normal views for your web application.
You can also create XML output:
format.xml { render xml: #users }
and other formats like PDF, or DOC, depending on the gems you are using.
See the Rails Guide Action Controller Overview for more information.

Related

Url changes when rendering view

I'm following the Ruby getting started guide, section 5.10 asks us to add code to check if the data added to the model is valid, if it isn't then we should call render 'new' to refresh the page with the users data:
def create
#article = Article.new(article_params)
if #article.save
redirect_to #article
else
render 'new'
end
end
I've noticed though that the moment I submit wrong data my url changes from :
http://localhost:3000/articles/new to http://localhost:3000/articles, why is that? The rendering seems to work since I get the error messages indicating my invalid input just like in the tutorial.
The html output looks slightly off too, there's an extra space between one of the labels and the text input field.
URL change because it's a PUT HTTP method, RoR use REST for CRUD actions, "In Rails, a resourceful route provides a mapping between HTTP verbs and URLs to controller actions. By convention, each action also maps to particular CRUD operations in a database."

Rails - How does the show and new action work

Very general question I was hoping someone could clarify for me. I'm looking at the basic generated scaffold code for a model called products. I noticed the new and show actions in the controller don't have much written in them. In fact, show is entirely empty and new only has the line "#product = Product.new". I know these 2 actions are supposed to go to a separate view. A view to show the resource, and a new form view to input info and create a resource, respectively.
So, I'm curious how that actually happens. Other actions have redirect_to :some_path which makes sense, but how exactly does "render action 'show', location: #product " bring up the items show page when the action is empty? Also how is that different from redirect_to #product ?
thanks
Will
Render produces a string that will displayed as the response to the request to the application.
redirect_to produces a response header resulting in a new request to the application.
The render action 'show', location: #product uses the the file app/views/products/show.html.erb with #product as a parameter to produce the html which will be returned.
The reason some of the controller functions are empty is that rails are using defaults. So if you don't tell rails what to render then rails will look for a file in the appropriate location.
Methods ending with redirect_to are usually post/patch requests saving something in your database and after the requested action has been performed they redirect the user to a method meant for displaying information.

How do I display a d3.js circle pack graph with RoR?

I am trying to set up a graph like this http://bl.ocks.org/4063269#index.html with d3.js:
I need to do this by putting methods in a controller and the js in a .html.haml file. I have made the controllers, but have absolutely no idea how to write the methods.
The methods need to take values from a sqlite3 database and convert it into JSON for the d3.js to use. Could someone get me started? I have no idea what to do right now...
Unfortunately the question you are making is too open, with more details you will get more help ;)
So the javascript library is going to make ajax call to your application, and your application should respond with json?
In that case, you can just do the routing on config/routes.rb, and then you just write a method like this:
class MyController < ApplicationController
def values_for_js
my_data = MyModel.calculate_data
respond_to do |format|
format.json { render json: my_data.to_json }
end
end
end
And your js should request something like http://mywebsite.com/values_for_js.json (or it can say in the ajax request that a json format is expected). If you are not able to make the json request, you can just use format.js instead of format.json

How can I consume a RABL API from within the application?

I'm working on exposing an API using RABL. Exposing the views is easy enough, but I've run into trouble having my own application consume those views.
For example, assume I have an endpoint at http://example.com/api/articles, which produces a JSON representation of the articles.
In my ArticlesController#index action, I wish to render a (HAML) view that shows a list of the articles. Rather than duplicate the logic from ArticlesApiController#index, I want to simply use that data—i.e., I want to say "go get this data from the /articles API endpoint," and then pass that data to the HAML view.
How can I do that? Or, is this the wrong way to go about doing this?
Watch this screencast on RABL.
In your view you can add the data from RABL as follows(taken from railscast sample):
<div id="articles"
data-articles="<%= render(template: "articles/index.json.rabl") %>">
Note
You can make the data access even more simple by using the gon gem.
In your controller
def index
#articles = Article.all
# initialize the JS variable upon HTML request
gon.rabl if request.format == Mime::HTML
end
Now you can access the data in the javascript as follows:
alert(gon.articles)

How to modify the default RoR behavior to AJAX CRUD?

I want a table to do CRUD, but I want it in an Ajax way, how can I modify the default RoR behavior, any suggestions on that?
I tried comment these code in destroy method, but it don't work, it saw missing the destroy.erb:
respond_to do |format|
format.html { redirect_to(categories_url) }
format.xml { head :ok }
end
It will default to HTML if you don't give (and accept) a different response. Check out this railscast to see how to set up an AJAX request and response with RJS (there's another on how to do it with jQuery).
Basically you'll need a format.js line. You can also make a view of the form .js.erb where you write JavaScript to run on the server response.
As a side note though, unless you have a very specific website, I'd suggest not doing only AJAX. It's not very accessible for users without JavaScript, like blind users with a screenreader.

Resources