Search code examples
ruby-on-railsrubymodel-view-controllerrespond-to

How does `respond_to` function in rails work?


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.


Solution

  • 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.