Ruby-on-Rails
  Home arrow Ruby-on-Rails arrow Page 2 - Options for Web Applications with Ruby on ...
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Moblin 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
RUBY-ON-RAILS

Options for Web Applications with Ruby on Rails
By: O'Reilly Media
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 3
    2007-03-29

    Table of Contents:
  • Options for Web Applications with Ruby on Rails
  • 15.5 Displaying Templates with Render
  • 15.6 Integrating a Database with Your Rails Application
  • 15.7 Understanding Pluralization Rules

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    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

    More Ruby-on-Rails Articles
    More By O'Reilly Media


       · This article is an excerpt from the book "Ruby Cookbook," published by O'Reilly. We...
     

    Buy this book now. This article is excerpted from chapter 15 of the Ruby Cookbook, written by Lucas Carlson and Leonard Richardson (O'Reilly, 2006; ISBN: 0596523696). Check it out today at your favorite bookstore. Buy this book now.

    RUBY-ON-RAILS ARTICLES

    - Iterating and Incrementing Strings in Ruby
    - Comparing and Manipulating Strings in Ruby
    - Strings in Ruby
    - Ruby On Rails: Making Your First Dynamic Site
    - Ruby on Rails: Beginning Rails
    - Ruby: Modules, Mixins, Fixins, and Rails
    - Controlling Information Access with the Rail...
    - URLs, Filters and the Rails Action Controller
    - Flash and the Rails Action Controller
    - Rails Action Controller
    - Dropping and Sorting with AJAX and script.ac...
    - Drag and Drop with script.aculo.us and Rails
    - Introducing script.aculo.us
    - Ruby Classes and Objects
    - Ruby Loops






    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 4 hosted by Hostway
    Stay green...Green IT