Wednesday, January 10, 2018

Rails render, and redirect_to, head explained (just a memo)

Sometimes  dummy developers like me suffer to understand what on earth the render is, which is often described in the rails codebase, controllers and to some extent it looks obvious that it let pages redirected to another page, but not sure what in detail it is going on, since there are so many parameters. Rails is designed in the concept of convention over configuration, which I personally am not fan of, relies on hidden rules and variables which cannot been visible with a glance at the narrow class.

Here is the blief explanation of what these methods are:

render: (ActionController::Base#render)
  send back full response to the browser
redirect_to:
  send http redirect status code to the browser
head:
  send HTTP header to browser



Okay, then lets find out what these notations are about.

render

by default, render takes argument stands for its actions, such as:

def update
  ...
  render "edit" # or this can be symbol :edit
end

Then you can go to edit.html.erb

In the controler book_controller.rb, you can render the action of another controller products such as:

render "products/show"
render template: "products/show" # same as above


You also can return page with simple plain text such as:

render plain: "asshole"

or the other forms of data:
render html: "<p>aaa</p>".html_safe
render json: ...
render xml: ...
render js: ...


Options for render is as follows:

    :content_type
    :layout
    :location
    :status
    :formats


you can add MIME type declaration with the content_type option such as:

render file: filename, content_type: "application/rss"

location options sets the HTTP location header:

render xml: photo, location: photo_url(photo)


status option allows you to return the HTTPStatus:

render status: 500
render status: :forbidden


format option converts the original page, usually html to the other file format:

render formats: :xml
render formats: [:json, :xml]


Layout

layout is the kind of pre-set webpage layout template which can be reused by each view. it is by default located under app/view/layout

It is going to be called such as:

class ProductsController < ApplicationController
  layout "inventory"
  #...
end

the thing is, once you define the layout in the controller, the corresponding views under product/*.html.erb follows the layout defined there. (inventory)

You can choose layout at runtime:

class ProductsController < ApplicationController
  layout :products_layout

  def show
    @product = Product.find(params[:id])
  end

  private
    def products_layout
      @current_user.special? ? "special" : "products"
    end

end


Conditional Layout

In the example below, the views except index and rss can load the product layout.

class ProductsController < ApplicationController
  layout "product", except: [:index, :rss]
end


render_partials 

There is the way to partially borrow another view in a single view.

http://api.rubyonrails.org/classes/ActionView/PartialRenderer.html


redirect_to

it takes as argument direct target URL:

redirect_to photos_url
redirect_back(fallback_location: root_path)

use different status code for redirection

it is usually 302 by default but you can customize it:

redirect_to photos_path, status: 301


the difference between redirect_to and render is, redirect_to does not pass anything between pages, whereas render passes those shared state.


http://guides.rubyonrails.org/layouts_and_rendering.html

No comments:

Post a Comment