Home arrow Ruby-on-Rails arrow Page 2 - Options for Web Applications with Ruby on Rails
RUBY-ON-RAILS

Options for Web Applications with Ruby on Rails


In this second part of a six-part series on web development and Ruby on Rails, you'll learn how to integrate a database with your RoR application and more. This article is excerpted from chapter 15 of the Ruby Cookbook, written by Lucas Carlson and Leonard Richardson (O'Reilly, 2006; ISBN: 0596523696). Copyright © 2006 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.

Author Info:
By: O'Reilly Media
Rating: 5 stars5 stars5 stars5 stars5 stars / 3
March 29, 2007
TABLE OF CONTENTS:
  1. · Options for Web Applications with Ruby on Rails
  2. · 15.5 Displaying Templates with Render
  3. · 15.6 Integrating a Database with Your Rails Application
  4. · 15.7 Understanding Pluralization Rules

print this article
SEARCH DEVARTICLES

TOOLS YOU CAN USE

advertisement
Options for Web Applications with Ruby on Rails - 15.5 Displaying Templates with Render
(Page 2 of 4 )

Problem

Railss default mapping of one action method to one view template is not flexible enough for you. You want to customize the template that gets rendered for a particular action by calling Rails's rendering code directly.

Solution

Rendering happens in the ActionController::Base#render method. Rails's default behavior is to call render after the action method runs, mapping the action to a corresponding view template. The foo action gets mapped to the foo.rhtml template.

You can call render from within an action method to make Rails render a different template. This controller defines two actions, both of which are rendered using the shopping_list.rhtml template:

  class ListController < ApplicationController
   
def index
     
@list = ['papaya', 'polio vaccine']
      render :action => 'shopping_list'
   
end

    def shopping_list
      @list = ['cotton balls', 'amino acids', 'pie']
    end
  end

By default, render assumes that you are talking about the controller and action that are running when render is called. If you call render with no arguments, Rails will work the same way it usually does. But specifying 'shopping_list' as the view overrides this default, and makes the index action use the shopping_list.rhtml template, just like the shopping_list action does.

Discussion

Although they use the same template, visiting the index action is not the same as visiting the shopping_list action. They display different lists, because index defines a different list from shopping_list.

Recall from Recipe 15.4 that the redirect method doesn't perform an immediate HTTP redirect. It tells Rails to do a redirect once the current action method finishes running. Similarly, the render method doesn't do the rendering immediately. It only tells Rails which template to render when the action is complete.

Consider this example:

  class ListController < ApplicationController
   
def index
     
render :action => 'shopping_list'
     
@budget = 87.50
   
end

    def shopping_list
      @list = ['lizard food', 'baking soda']
    end
  end

You might think that calling index sets @list but not @budget. Actually, the reverse is true. Calling index sets @budget but not @list.

The @budget variable gets set because render does not stop the execution of the current action. Calling render is like sealing a message in an envelope that gets opened by Rails at some point in the future. You're still free to set instance variables and make other method calls. Once your action method returns, Rails will open the envelope and use the rendering strategy contained within.

The @list variable does not get set because the render call does not call the shopping_ list action. It just makes the existing action, index, use the shopping_list.rhtml template instead of the index.rhtml template. There doesn't even need to be a shopping_list action: there just has to be a template named shopping_list.rhtml.

If you do want to invoke one action from another, you can invoke the action method explicitly. This code will make index set both @budget and @list:

  class ListController < ApplicationController
    def index
      shopping_list and render :action => 'shopping_list'
      @budget = 87.50
    end
 
end

Another consequence of this "envelope" behavior is that you must never call render twice within a single client request (the same goes for render's cousin redirect_to, which also seals a message in an envelope).

If you write code like the following, Rails will complain. You're giving it two sealed envelopes, and it doesn't know which to open:

  class ListController < ApplicationController
   
def plain_and_fancy
     
render :action => 'plain_list'
     
render :action => 'fancy_list'
   
end
  end

But the following code is fine, because any given request will only trigger one branch of the if/else clause. Whatever happens, render will only be called once per request.

  class ListController < ApplicationController
    def plain_or_fancy
      if params[:fancy]
        render :action => 'fancy_list'
      else
        render :action => 'plain_list'
      end
    end
  end

With redirect_to, if you want to force your action method to stop running, you can put a return statement immediately after your call to render. This code does not set the @budget variable, because execution never gets past the return statement:

  class ListController < ApplicationController
   
def index
     
render :action => 'shopping_list' and return
     
@budget = 87.50     # This line won't be run.
   
end
  end

See Also

  • Recipe 15.4, "Redirecting to a Different Location"
  • Recipe 15.14, "Refactoring the View into Partial Snippets of Views," shows examples of calling render within a view template


blog comments powered by Disqus
RUBY-ON-RAILS ARTICLES

- Adding Style with Action Pack
- Handling HTML in Templates with Action Pack
- Filters, Controllers and Helpers in Action P...
- Action Pack and Controller Filters
- Action Pack Categories and Events
- Logging Out, Events and Templates with Actio...
- Action Pack Sessions and Architecture
- More on Action Pack Partial Templates
- Action Pack Partial Templates
- Displaying Error Messages with the Action Pa...
- Action Pack Request Parameters
- Creating an Action Pack Registration Form
- Ruby on Rails Templates and Layouts
- Action Pack Controller Creation
- Writing an Action Pack Controller

Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 



© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 11 - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials