Making Software Wizards Easier
Let’s talk about software wizards. Your clients love wizards because they look better than long single-screen forms. Users like wizards because they feel like they’ve done less work even though they’ve actually done more work. Most engineers I know hate wizards.
Why? I think it is because we struggle to implement them cleanly. The tools and patterns we use for the rest of the application don’t always apply well to wizard implementation.
In this RailsConf talk, Andy Maleh does an excellent job explaining the pitfalls of the common approaches to wizards in Rails and suggests a reasonable solution:
To summarize, common approaches to Rails wizards add a lot of model and controller logic. They introduce temporary models and/or conditional validations. Many approaches require “cleanup” code to handle abandoned wizards. None of this feels good.
Andy’s solution is much better than most– it is clean and only relies on what Rails provides. However, I think it still has a big downside: it makes the Rails application more complex by adding many more models, more if-else controller logic, and “work in progress” models that the rest of the app needs to remember to ignore.
An Alternate Approach
I’d propose this: a wizard is a form of “rich editor.” It is the same as your WYSIWYG post editor or an inline image editor. A WYSIWYG editor is an improvement over a plain textarea that makes editing easier. A wizard is an enhancement over a plain form that makes entering complex information easier.
Your backend should be oblivious to which editor was used. Your Rails app probably doesn’t have a separate controller for posts made with the wysiwyg editor vs. posts made with the plain old textarea. You probably don’t have to periodically clean up a bunch of objects that represent individual sentences of some long abandoned blog post.
Start with the plain old form as baseline functionality for people with shaky 3G connections or JS disabled. Enhance this with a browser-side wizard component that handles work-in-progress. Only persist data to the server once you have a “whole model”– e.g. a complete user or order.
Your user gets a better experience and your service remains clean and simple. You will require no separate consideration of “in progress” and “completed” data in your server or database. No clean-up tasks are needed to destroy abandoned partial objects. Engineers, clients and end users can all be happy.