Ruby on Rails/ActionView/Rendering and Redirecting
Rendering and Redirecting
editIntroduction
editalready know how to manage your data with ActiveRecord. Now it is time to display your data. All data the view displays comes from the controller. Most of the time, you will work with HTML but you can also use Javascript inside your views (which of course can again be Rails generated) or different CSS.
The "Convention over Configuration" is also an essential part of the view: as mentioned in the beginning of this book, Rails is able to know which file for the view belongs to which action inside in the controller:
app/controller/products_controller.rb
def show
@product= Product.find(params[:id])
end
This action inside our products controller assumes that there is a view responding to the name:
app/views/products/show.html.erb
As you can see the file has 2 extensions: one is for the browser to display (HTML) and the other one tell Rails how to process it (erb= embedded ruby).
Rendering and Redirecting
editYou will come across 2 often used methods to display data render and redirect_to. A good example of how these two methods work can be seen in the example below:
This actions gets called when the user submitted updated data
As you can see both of our methods are used in this simple example. Whenever we successfully updated the name of a product, we get redirected to the index site of the products. If the update fails, we want to return to the edit view.
def update
@product= Product.find(params[:id])
if @product.update_attributes(params[:name])
redirect_to :action => 'index'
else
render :edit
end
end
There is an important difference between render and redirect_to: render will tell Rails what view it should use (with the same parameters you may have already sent) but redirect_to sends a new request to the browser.
Render
editRemember the "update" action above? When the update fails, we want to render the edit view with the exact same parameters as we did before, in this case we look for the "id" inside the database and populate the page accordingly. If you want to render another view use
render 'categories/show'
You can also display a file that is somewhere completely different on your web server
render :file => "/apps/some_folder/app/views/offers/index"
And of course, you can render simple text
render :text => "Hello World"
You may have already noticed that there is a "layout" folder inside your view. Whenever you use scaffolding to create parts of your application a file inside layout gets created. If you scaffold "Products" the file inside layout will be called products.html.erb. This file is responsible for the basic display of your sites matching the common name (in this example, it's products). Whenever you want to redirect your user to another layout you can use
render :layout => 'another_layout'
Whenever there is no proper layout file, Rails will display the page only with the styling provided inside the requested view. To use a specific layout inside your whole controller you can define the layout inside your Controller
class ProductsController < ApplicationController
layout "my_layout"
#our actions
end
For more infos about layouts, see "Layout Files"
redirect_to
editYou can use redirect_to in a similar manner as you do with render, but keep the big difference between render and redirect_to in mind.
With redirect_to you can easily send the user to a new resource, for example the index page of our products. To learn more about the paths and routing see the chapter on "routing"
redirect_to products_path
A very handy redirect_to option is :back
redirect_to :back
will send the user back to the site that he came from
Templates
editThere are several templating systems included with Rails each designed to solve a different problem.
- ERb - Embedded Ruby is the default templating system for Rails apps. All files ending with .rhtml are considered ERb templates.
- Builder - Builder templates are programmatic templates which are useful for rendering markup such as XML. All templates ending with .rxml are treated as builder templates and include a variable called xml which is an instance of XmlMarkup.
In addition to the built in template systems you can also register new template handlers using the ActionView::Base.register_template_handler(extension, class) method. A template handler must implement the initialize(base) method which takes the ActionView::Base instance and a render(text, locals) method which takes the text to be rendered and the hash of local variables. =