The concepts : Flow

What is a flow

A flow is an instance of the ActionFlow::Base class. It consists mainly of two things.

  • Mapping
    The instructions which tell the ActionFlow framework what to do and when to do it.
  • Step definitions
    The definition of what the declared steps do.

All the flow mapping must be done in Ruby objects standard initialize method. Then, we define the step definitions, if needed. More information on creating controllers is available.

Mapping

The mapping is the first part of an ActionFlow controller. It defines the logical arrangement of steps and what to do when a given event or error is encountered.

Here’s a sample flow step mapping.

 
 action_step :init do
  
   # Tells what to do when the 'success' event is returned
   on :success => :display_something
  
   # Maps an error to a step call
   upon :SomeCustomException => :handle_custom_error
  
 end
  
   
 view_step :display_something do
  
   # We define what to do depending on the submit button value.
   # As you can see, the on method can handle a block
   on {
     :ok => :do_something,
     :cancel => :clean
   }
  
 end

The code which is included in the step definitions are entirely up to the step type used. Please refer to the proper documentation. One important thing to know though is that all steps inherit from Flow Step. Therefore, all it’s instructions are available to any step type.

The on instruction tells what to do when a given event is returned, while the upon instruction tells what to do when a given error is rescued.

In the examples above, the init step is simply redirecting to the display_something step if the success event is returned. If an error of the SomeCustomException class gets rescued by ActionFlow, the handle_custom_error step will be executed next.

Step Definitions

Once the mapping is established, you have to define the steps themselves. Defining steps is as simple as this.

 
 def init
 
   # Nothing to do, just a sample after all...
   # Let's just send a 'success' event.
   event :success
 
 end
  
  
 def display_something	
  
   # A view step can call all the 'render' functions it wants.
   # It can also be a redirect, or whatever is needed--let's render.
   render_partial :whatever
  
   # If the step wants the framework to display the view, simply return 
   # the 'render' Event. 'render' is a reserved event name. The framework knows
   # that it must now display a view.
   event :render
  
 end

Also note that not all the steps need an explicit definition block. The View Step, for example, doesn’t need it. It has a default behavior and therefore knows what to render.

Flow instructions

Just like a step, some instructions tell the flow what to do on certain conditions.

  • Start Step
    Tells the flow with what step to start with.
  • End Step
    Tells the flow when we consider that a flow has reached an end.
  • Error handling
    A flow can be told what to do when some errors are not handled by the steps.
  • Invalid flow redirection
    Tells where to redirect requests which submitted invalid flow ids.

Start Step

Subclasses of ActionFlow::Base must define a start step to call upon new execution of the flow. The start step is defined as follows.

 start_with :init

The step name passed as an argument will be called and must be defined in the controller, or else an ActionFlowError will be thrown. Of course, the obligation to define the step explicitly depends on the step type. As we said earlier, the View Step doesn’t need an explicit definition block.

End Step

Subclasses of ActionFlow::Base must define which is the flow end step. After execution of this step (usually a view step which redirects), the flow data will be removed from the user session data hash. The end step is defined as follows.

 end_with :back_to_homepage

The step name passed as an argument will be called and must be defined in the controller, or else an ActionFlowError will be thrown. Of course, the obligation to define the step explicitly depends on the step type. As we said earlier, the View Step doesn’t need an explicit definition block.

Error handling

A flow can be told what to do when some errors are not handled by the steps. The upon keyword does just that. It’s syntax is simple and straight forward.

upon :MyErrorClass => :step_name_to_go_to

Adding this snippet to the initialize method of a flow controller will tell it to route the flow to the step named step_name_to_go_to if an error of class or a subclass of MyErrorClass is raised. Note that if the error is raised from a step definition which is already handling this error class, the flow will not be asked to handle it.

Invalid flow redirection

When a request arrives to a flow controller, there are three possibilities.

  1. No flow execution key was provided, so the flow is routed to the step indicated by the start_with instruction.
  2. A valid flow execution key was provided, so the flow can be resumed from it’s last execution state.
  3. A flow execution key was provided, but it does not correspond to an existing flow id nor flow state

In the last scenario, we have the option to redirect any such request to a specific URL. The redirect_invalid_flows does exactly that.

redirect_invalid_flows :url => { :controller => :static, :action => :homepage }

Adding this snippet of code to the controller initialize method will tell the controller to redirect any request which gave an invalid flow id to the /static/homepage page via an HTTP 303 error code. If you don’t include this instruction in your controller mapping, it will simply render a standard Rails error page with a neat little message explaining what just happened.

~~DISCUSSION~~

 
flow.txt · Last modified: 2007/06/06 16:18 by lucboudreau
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki

Creative Commons License
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 License.