URLs, Filters and the Rails Action Controller - 4.11 Rendering Actions
(Page 4 of 4 )
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
Please check back next week for the conclusion to this article.
| DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware. |
|
This article is excerpted from chapter four of the Rails Cookbook, written by Rob Orsini (O'Reilly, 2007; ISBN: 0596527314). Check it out today at your favorite bookstore. Buy this book now.
|
|