Ruby-on-Rails
  Home arrow Ruby-on-Rails arrow Page 4 - Controlling Information Access with the Ra...
IBM developerWorks
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  
Dedicated Servers  
Actuate Whitepapers 
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

Controlling Information Access with the Rails Action Controller
By: O'Reilly Media
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 2
    2008-02-14

    Table of Contents:
  • Controlling Information Access with the Rails Action Controller
  • 4.13 Sending Files or Data Streams to the Browser
  • 4.14 Storing Session Information in a Database
  • 4.15 Tracking Information with Sessions
  • 4.16 Using Filters for Authentication

  • 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

    Free Web 2.0 Code Generator! Generate data entry and reporting .NET Web apps in minutes. Quickly create visually stunning, feature-rich apps that are easy to customize and ready to deploy. Download Now!

    Controlling Information Access with the Rails Action Controller - 4.15 Tracking Information with Sessions


    (Page 4 of 5 )

    Problem

    You want to maintain state across several web pages of an application without using a database.

    Solution

    Use Rails’s built-in sessions to maintain state across multiple pages of a web application, such as the state of an online quiz.

    Create an online quiz that consists of a sequence of questions, one per page. As a user proceeds through the quiz, her score is added to the total. The last screen of the quiz displays the results as the number correct out of the total number of questions.

    Create a QuizController that includes a data structure to store the questions, optional answers, and correct answers for each question. The controller contains methods for displaying each question, checking answers, displaying the results, and starting over.

    app/controllers/quiz_controller.rb:

      class QuizController
    < ApplicationController

        @@quiz = [
          { :question => "What's the square root
    of 9?",
            :options => ['2','3','4'],
            :answer => "3" },
          { :question => "What's the square root
    of 4?",
            :options => ['16','2','8'],
            :answer => '16' },
          { :question => "How many feet in
    a mile?",
            :options => ['90','130','5,280',
    '23,890'],
            :answer => '5,280' },
          { :question => "What's the total area
    of irrigated land in Nepal?",
            :options => ['742 sq km','11,350
    sq km','5,000 sq km',
                          'none of the above'],
            :answer => '11,350 sq km' },
      ]

      def index
        if session[:count].nil?
          session[:count] = 0
        end
        @step = @@quiz[session[:count]]
      end

      def check
        session[:correct] ||= 0
        if params[:answer] == @@quiz[session[:count]][:answer]
         
    session[:correct] += 1
        end
        session[:count] += 1
          @step = @@quiz[session[:count]]
          if @step.nil?
            redirect_to :action => "results"
          else
            redirect_to :action => "index"
          end
        end

        def results
          @correct = session[:correct]
          @possible = @@quiz.length
        end

        def start_over
          reset_session
          redirect_to :action => "index" 
        end
      end

    Create a template to display each question along with its optional answers: app/views/quiz/index.rhtml:

      <h1>Quiz</h1>

      <p><%= @step[:question] %></p>

      <% form_tag :action => "check" do %>
        <% for answer in @step[:options] %>
          <%= radio_button_tag("answer", answer, checked = false) %>
            <%= answer %>;
        <% end %>
        <%= submit_tag "Answer" %>
      <% end %> 

    At the end of the quiz, the following view displays the total score along with a link prompting to try again:

    app/views/quiz/results.rhtml:

      <h1>Quiz</h1>

      <p><strong>Results:</strong>
        You got <%= @correct %> out of <%= @possible %>!</p> 

      <%= link_to "Try again?", :action => "start_over" %>

    Discussion

    The Web is stateless, which means that each request from a browser carries all the information that the server needs to make the request. The server never says, “Oh, yes, I remember that your current score is 4 out of 5.” Being stateless makes it much easier to write web servers but harder to write complex applications, which often need to remember what went before: they need to remember which questions you’ve answered, what items you’ve put in your shopping cart, and so on.

    This problem is solved by the use of sessions. A session stores a unique key as a cookie in the user’s browser. The browser presents the session key to the server, which can use the key to look up any state that it has stored as part of the session. The Web interaction is stateless: the HTTP request includes all the information needed to complete the request. But that information contains information the server can use to look up information about previous requests.

    In the case of the quiz, the controller checks the answers to each question and maintains a running total, storing it in the session hash with the :correct key. Another key in the session hash is used to keep track of the current question. This number is used to access questions in the @@quiz class variable, which stores each question, its possible answers, and the correct answer in an array. Each question element consists of a hash containing all the information needed to display that question in the view.

    The index view displays a form for each question and submits the user’s input to the check action of the controller. Using session[:count], the check action verifies the answer and increments session[:correct] if it’s correct. Either way, the question count is incremented, and the next question is rendered.

    When the question count fails to retrieve an element—or question—from the @@quiz array, the quiz is over, and the results view is rendered. The total correct is pulled from the session hash and displayed with the total number of questions, which is determined from the length of the quiz array.

    A quiz such as this lends itself reasonably well to the convenience of session storage. Be aware that sessions are considered somewhat volatile and potentially insecure, and are usually not used to store critical or sensitive information. For that type of data, a traditional database approach makes more sense.

    Figure 4-3 shows the four steps of the session-driven online quiz.

    Rails session support is on by default. As the solution demonstrates, you can access the session hash as if it’s just another instance variable. If your application doesn’t need session support, you can turn it off for a controller by using the :disabled option of Action Controller’s session method in the controller’s definition. The call to disable session support for a controller may also include or exclude specific actions within a controller by passing a list of actions to session’s :only or :except options. The following disables session support for the display action of the NewsController:

      class NewsController
    < ActionController::Base
        session :off, :only => "display"
      end

    To turn session support off for your entire application, pass :off to the session method within your ApplicationController definition:

      class ApplicationController
    < ActionController::Base
       
    session :off
      end


    Figure 4-3.  An online quiz saving state with sessions

    See Also

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


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

    Buy this book now. This article is excerpted from chapter four of the Rails Cookbook, written by Rob Orsini (O'Reilly, 2007; ISBN: 0596527314). Check it out at your favorite bookstore. Buy this book now.

    RUBY-ON-RAILS ARTICLES

    - 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
    - Ruby Conditionals
    - Ruby Operators and Arrays
    - Ruby for the Newbie






    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 2 hosted by Hostway