A flow is an instance of the ActionFlow::Base class. It consists mainly of two things.
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.
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.
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.
Just like a step, some instructions tell the flow what to do on certain conditions.
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.
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.
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.
When a request arrives to a flow controller, there are three possibilities.
start_with instruction.
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~~
This work is licensed under a
Creative Commons Attribution-Share Alike 3.0 License.