Upload
andymaleh
View
8.096
Download
2
Tags:
Embed Size (px)
Citation preview
Ultra Light & Maintainable Wizards in RailsAndy Maleh
President and Chief Journeyman
Soft Buzz
Overview
Why Use A Wizard?
Wizard Example
Wizard Implementation Goals
1001 Wizard Implementations
Ultra Light & Maintainable Wizard
Why Use A Wizard?
Avoid overwhelming user with a huge
form
Why Use A Wizard?
Simplify a workflow into multiple steps
Why Use A Wizard?
Help the user by providing guidance
Wizard Example
Event Registration Wizard
Wizard Example
Step 1 – Personal Info
Wizard Example
Step 2 – Background Info
Wizard Example
Step 3 – Review
Wizard Example
Step 4 – Payment
Wizard Example
Steps Done – Order Confirmation
Wizard Implementation Goals
REST
MVC
OO
Non-Functional Requirements:
Productivity
Maintainability
Performance
Security
1001 Wizard
Implementations1. One Controller/ActiveRecord Per Wizard Step
• Create a REST resource per wizard step
• Multiple ActiveRecords with distinct validations
• Multiple Controllers
• Multiple sets of Views and Helpers
• Bind every wizard step form to corresponding ActiveRecord
• Have each wizard step controller redirect to the next one on create or update
1001 Wizard
Implementations1. One Controller/ActiveRecord Per Wizard Step
Step 1
Controller
Step 2
Controller
Step 3
Controller
Step 4
Controller
Create &
Redirect to New
Create &
Redirect to New
Create &
Redirect to New
Step 1
ActiveRecord
Step 2
ActiveRecord
Step 3
ActiveRecord
Step 4
ActiveRecord
1001 Wizard
Implementations1. One Controller/ActiveRecord Per Wizard Step
Pros
Easy to understand and follow
RESTful
1001 Wizard
Implementations1. One Controller/ActiveRecord Per Wizard Step
Cons
Redundant code across controllers
Repetitive redirect logic
Redundant authentication logic
Similar model loading logic
Similar REST actions
Tying database tables to presentation details
1001 Wizard
Implementations1a. One Controller/Presenter Per Wizard Step
• Create one ActiveRecord
• Create a controller and ActiveModel presenter per wizard step
• Have each ActiveModel presenter manage its own step validation logic
• Bind every wizard step form to corresponding ActiveModel presenter
• Have each wizard step controller redirect to the next one on create or update
1001 Wizard
Implementations1a. One Controller/Presenter Per Wizard Step
Step 1
Controller
Step 2
Controller
Step 3
Controller
Step 4
Controller
Create &
Redirect to New
Create &
Redirect to New
Create &
Redirect to New
Step 1
Presenter
Step 2
Presenter
Step 3
Presenter
Step 4
Presenter
ActiveRecord
1001 Wizard
Implementations1a. One Controller/Presenter Per Wizard Step
Pros
Easy to understand and follow
RESTful
Works with one ActiveRecord
1001 Wizard
Implementations1a. One Controller/Presenter Per Wizard Step
Cons
Redundant code across controllers
Repetitive redirect logic
Redundant authentication logic
Similar model loading logic
Similar REST actions
Too much presenter validation/persistence
management code
1001 Wizard
Implementations1b. One Action/Presenter Per Wizard Step
• Create one ActiveRecord
• Create one controller with a different new and create action variation per wizard step
• e.g. new_step1, create_step1, new_step2, create_step2, etc…
• Create a different ActiveModel presenter per wizard step
• Have each ActiveModel presenter manage its own step validation logic
• Bind every wizard step form to corresponding ActiveModelpresenter
• Have each wizard step action redirect to the next one on create
1001 Wizard
Implementations1b. One Action/Presenter Per Wizard Step
Controller
Step 1 New
Step 1 Create
Step 2 New
Step 2 Create
Step 3 New
Step 3 Create
Step 4 New
Step 4 Create
Step 1
Presenter
Validation/Persistance
Adapter
Step 2
Presenter
Validation/Persistance
Adapter
Step 3
Presenter
Validation/PersistanceAdapt
er
Step 4
Presenter
Validation/Persistance Adapter
ActiveRecord
Create Step &
Redirect to New Step
1001 Wizard
Implementations1b. One Action/Presenter Per Wizard Step
Pros
Easy to understand and follow
Works with one ActiveRecord
Lighter controller code
Reused controller hooks (e.g. authentication)
1001 Wizard
Implementations1b. One Action/Presenter Per Wizard Step
Cons
Not RESTful
Redundant code across actions
Repetitive redirect logic
Repetitive update logic
Too much presenter management code
1001 Wizard
Implementations2. Session Accumulation
Create one ActiveRecord
Have multiple Controllers or Actions accumulate
wizard step data in the session
Have ActiveModel presenters handle
validation/forms
On the final step, create ActiveRecord running all
validationsStep 1
Step 2
Step 3
Step 4
Accumulate
in Session
Accumulate
in Session
Accumulate
in Session
Create
ActiveRecor
d
1001 Wizard
Implementations2. Session Accumulation
Pros
Works with one ActiveRecord
1001 Wizard
Implementations2. Session Accumulation
Cons
Reliance on session has implications on scalability
Controller code more complex due to managing
session data storage
Validations defined twice, once per ActiveModel
presenters used for form validation and once in the
actual ActiveRecord
1001 Wizard
Implementations3. Hidden Value Accumulation
Same as session value accumulation except the
controller manages data coming from a request
parameter
Same pros and cons as Session Value
Accumulation except that it has no scalability
implications
NOTE: hidden value must be encrypted for
security
1001 Wizard
Implementations4. State Machine
Create one ActiveRecord
Make ActiveRecord a state machine managing steps:
adding a step column
add current_step, next_step, and prev_step methods
Different view per step
Have single ActiveRecord manage each step
validations by relying on conditional validations. For
example:
validate :phone,
presence: true,
if: lambda {current_step==“shipping”}
1001 Wizard
Implementations4. State Machine
Pros
Works with one ActiveRecord
Simpler step management logic in one controller
1001 Wizard
Implementations4. State Machine
Cons
Puts presentation concerns in Model (breaks MVC)
The state machine wizard must be a layer on top of
the Model. It has nothing to do with the business
model.
Stores an extra column in the database for purely
presentation-related reasons
Can be avoided with session storage of state, opening
a different can of worms (controller complexity)
More complexity in declaring validations due to
conditions and potentially overloading the Model
1001 Wizard
Implementations5. Gems
Wizardry: state machine in model
Wicked: clean state machine in controller (better)
but no validation support beyond conditional
validation
Rails-Wizard-Generator: XML XML XML
Stepper: Nice support for steps in model and
controller
Wizard Implementation
GoalsREST
MVC
OO
Non-Functional Requirements:
Productivity
Maintainability
Performance
Security
Ultra Light & Maintainable
WizardPhilosophy:
A wizard is simply a builder of a model
Every step is simply a partial data-view of the
model
REST resource is still the model itself and thus
must have a single controller
Models must manage validations without
conditions by relying on step-polymorphism
View forms are presented based on step-
polymorphism
Ultra Light & Maintainable
WizardDetails:
Create one main ActiveRecord model
Create “step submodels” subclassing the main model:
Each presents a partial view of the main model
Each has validations only for its step, thus no conditionals
Each has before and after initialization for that step
Create a single controller:
It begins wizard by creating main ActiveRecord
Every step represents an Edit action of a “step submodel”
Create a different view per step, each binding to “step submodel” to ensure the right validations are triggered
Ultra Light & Maintainable
Wizard
Controller
Create
Edit
Update
Step 1
ActiveRecord
Validations/Step Logic
Step 2
ActiveRecord
Validations/Step Logic
Step 3
ActiveRecord
Validations/Step Logic
ActiveRecord
Step 4
ActiveRecord
Validations/Step Logic
Update &
Redirect to Edit
Ultra Light & Maintainable
WizardCode Review in Editor
Review
Why Use A Wizard?
Wizard Example
Wizard Implementation Goals
1001 Wizard Implementations
Ultra Light & Maintainable Wizard
Contact
Andy Maleh
BLOG: http://andymaleh.blogspot.com
TWITTER: @AndyMaleh
WEBSITE:http://www.softbuzz.ca