0

This is the default Rails code generated. I understand what the code does (from the explanation in the documentation) but not how it does.

  1 class PostsController < ApplicationController
  2   # GET /posts
  3   # GET /posts.json
  4   def index
  5     @posts = Post.all
  6 
  7     respond_to do |format|
  8       format.html # index.html.erb
  9       format.json { render json: @posts }
 10     end
 11   end

What I understand:

  • Post.all returns an array of all the posts which is saved in the instance variable @posts
  • respond_to function takes the default 'block' (an anonymous function block which takes one parameter 'format'
  • Depending on the requested format, corresponding output is returned

What I don't understand:

  • How does that actually work? Line# 8 calls a function html method of format object, no matter whatever format is passed. What does the html method do? Why both methods are called every time? Are they?
  • Why does json method require an argument (block that calls render) but html method does not need any argument
  • Does this function return anything? It looks like it returns the return value of json method.

I am new to ruby and rails and I am getting started with example and would like to know in detail what each line does.

balki
  • 26,394
  • 30
  • 105
  • 151

2 Answers2

2

The methods called on format tell Rails that a response type is available. In the case above, Rails is told that the 2 acceptable response types (in order of preferences) are html and json.

Rails then picks a response type, based on the preference ordering given and the headers of a request. Having made that choice, the block corresponding to the chosen format is called. Until then the blocks passed to the format methods haven't been called - just saved in case that response type is needed.

If a response type has no block, this means that the default action for that response type should be taken. In the case of 'html' this means "find an html template and render it", similar to the implicit render that happens at the end of the action.

All methods in ruby have a return value, but this method's return value is not documented as being anything in particular - don't rely on it.

Frederick Cheung
  • 83,189
  • 8
  • 152
  • 174
  • When is the index method called and when is the block passed to respond_to called? Each of them are called for every request or once when starting up the server? How does the `format.html` method have access to `@posts` instance variable? I hope it is part of rails magic and not default ruby. So, only code that can be written inside the block passed to `respond_to` is method calls of `format` function (or someother way to tell rails the different possible response types)? – balki Oct 19 '15 at 06:29
  • This happens on every request. You can write anything you want inside the respond_to block. – Frederick Cheung Oct 19 '15 at 06:57
0

The answer in the comment (Rails: How does the respond_to block work?) is what you need for a base-level explanation.

The source code (I think?) can be found here: /lib/action_controller/metal/mime_responds.rb


MIME

The bottom line is the respond_to block deals with the MIME (Multipurpose Internet Mail Extensions) types you're sending to your app.

This is a denotation of the media type that you're looking to load from a particular resource, and as such, is what you should be looking to return as a developer.

Rails' respond_to formatter is what allows you to do this:

What that says is, “if the client wants HTML in response to this action, just respond as we would have before, but if the client wants XML, return them the list of people in XML format.” (Rails determines the desired response format from the HTTP Accept header submitted by the client.)

Although mimes are used for "media" of any kind, Rails' scope mainly extends to the type of request - IE JS/JSON etc, most commonly referred to in the content/type header of AJAX requests.


Use Cases

In regards to how the function works within rails, you need to appreciate that each time you send a request to your application, it will be formatted in a certain way.

Most requests will be standard HTML, however there will be sometimes when JS or JSON requests need to be returned. Use cases for these could be the likes of an API or an asynchronous request:

enter image description here

Ajax requests are sent through XML or JSON - which typically denotes different methods in the controller action. Although not always the case, it generally gives you the ability to define specific functionality depending on the request type you invoke.

The Rack:Request class deals with this in the controller:

request.xhr?

--

In regards to how this works technically, you'll be best looking at the answers in this question. I know that if I send a JSON request to Rails, I can format the reply in JSON too.

Rails takes the MIME type and responds accordingly.

Community
  • 1
  • 1
Richard Peck
  • 76,116
  • 9
  • 93
  • 147