Recipe 4.11. Rendering Actions


Problem

You have an action that has gathered some data from your model, perhaps based on a user-defined query, and you want to render another action to display the results.

Solution

Use render :action => 'action_name', where action_name is the name of the action that displays the result. The search method in CategoriesController does just that:

app/controllers/categories_controller.rb:

class CategoriesController < ApplicationController   def search_form   end   def search      @categories = Category.find(:all,                                 :conditions =>                                      ["name like ?", "%#{params[:cat]}%"])     if @categories       render :action => 'search_results'     else           flash['notice'] = 'No Category found.'       render :action => 'search_form'     end   end   def search_results     @category = Category.find(params[:id])   end end

Discussion

In the solution, if the find call in search action successfully returns a category, the search_results action is rendered. At that point, Rails looks for a template file named after that action, under a directory named after the controller, i.e., app/views/categories/search_results.rhtml.

This is probably the most common pattern of control flow in Rails: you perform a query, or some other immutable action, and then you display the results of that action with a second action. Ideally, these actions are separate because they do distinctly different tasks (the first allows the user to make a query; the second displays the results), and combining the two actions into a single method inhibits code reuse.

The solution calls render only once, whether or not a category is found in the database. It's possible to render an action that renders another action, and so on, but you'll get a DoubleRenderError if you try to render twice within the same action. Rails 0.13 added this error message to help avoid confusing side effects of parallel render attempts.

An action can continue processing after a call to render, but it usually makes more sense to call render at the end of the action (just before the return statement, if there is one). This way, the rendered action can communicate success or failure to the user.

Rails renders actions within the layout that is associated with the action's controller. You can optionally render with no layout by specifying :layout=>false:

render :action => "display", :layout => false

Or you can specify another layout by supplying the name of that layout:

render :action => "display", :layout => "another_layout" 

See Also

  • Section 4.7"




Rails Cookbook
Rails Cookbook (Cookbooks (OReilly))
ISBN: 0596527314
EAN: 2147483647
Year: 2007
Pages: 250
Authors: Rob Orsini

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net