Ultra Light and Maintainable Rails Wizards at RailsConf 2014
-
Upload
andymaleh -
Category
Technology
-
view
198 -
download
0
Transcript of Ultra Light and Maintainable Rails Wizards at RailsConf 2014
Overview• Why Use A Wizard?
• Wizard Example
• Wizard Implementation Goals
• 1001 Wizard Implementations
• Ultra Light & Maintainable Wizard
Wizard Implementation Goals
• Rails Server must persist progress on every stepo JS Client-Side Persistence is Out Of Scope
• REST
• MVC
• OO
• Non-Functional Requirements:o Productivity
o Maintainability
o Performance
o Security
1001 Wizard Implementations
1. One Controller Per Wizard Step
• Create a REST resource per wizard step• One ActiveRecord with conditional validations
• Multiple Controllers
• Multiple sets of Views and Helpers
• Have each wizard step controller redirect to the
next one on create or update
1001 Wizard Implementations
1. One Controller Per Wizard Step
Step 1Controller
Step 2Controller
Step 3Controller
Step 4Controller
Create & Redirect to New
Create & Redirect to New
Create & Redirect to New
Step 1ActiveRecord
1001 Wizard Implementations
1. One Controller Per Wizard Stepo Critique
• Redundant code across controllers
o Repetitive redirect logic
o Redundant authentication logic
o Similar model loading logic
o Similar REST actions
• Tying database tables to presentation details
1001 Wizard Implementations
2. 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
ActiveModel presenter
• Have each wizard step action redirect to the next one
on create
1001 Wizard Implementations
2. One Action Per Wizard Step
Controller
Step 1 NewStep 1 CreateStep 2 New
Step 2 CreateStep 3 New
Step 3 CreateStep 4 New
Step 4 Create
Step 1Presenter
Validation/PersistanceAdapter
Step 2Presenter
Validation/PersistanceAdapter
Step 3Presenter
Validation/PersistanceAdapter
Step 4Presenter
Validation/Persistance Adapter
ActiveRecord
Create Step & Redirect to New Step
1001 Wizard Implementations
2. One Action Per Wizard Stepo Critique
• Not RESTful
• Redundant code across actions
o Repetitive redirect logic
o Repetitive update logic
• Too much presenter management code
1001 Wizard Implementations
3. Session Accumulationo Create one ActiveRecord
o Have multiple Controllers or Actions accumulate wizard step data in the
session
o Have ActiveRecord in-memory conditional validations run on every step
o On the final step, create ActiveRecord running all validations
Step 1
Step 2
Step 3
Step 4
Accumulate in Session
Accumulate in Session
Accumulate in Session
Create ActiveRecord
1001 Wizard Implementations
3. Session Accumulationo Critique
• 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 Implementations
4. Hidden Value Accumulationo Same as session value accumulation except the controller manages data
coming from a request parameter
o Same pros and cons as Session Value Accumulation except that it has no
scalability implications
o NOTE: hidden value must be encrypted for security
1001 Wizard Implementations
5. State Machineo Create one ActiveRecord
o Make ActiveRecord a state machine managing steps:
• adding a step column
• add current_step, next_step, and prev_step methods
o Different view per step
o 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 Implementations
5. State Machineo Critique
• Puts presentation concerns in Model (breaks MVC)
o 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
o 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 Implementations
1001. 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 Goals Review
• Rails Server must persist progress on every stepo JS Client-Side Persistence is Out Of Scope
• REST
• MVC
• OO
• Non-Functional Requirements:o Productivity
o Maintainability
o Performance
o Security
Ultra Light & Maintainable Wizard
• Philosophy:o Every step is simply a partial data-view of the model
Ultra Light & Maintainable Wizard
• Philosophy:o REST resources are the model and model parts edited during a step.
Ultra Light & Maintainable Wizard
• Philosophy:o Models must manage validations without conditions by relying on step-
polymorphism
Ultra Light & Maintainable Wizard
• Philosophy:o Step view forms are maintained independently with no conditionals as
well
step1.html.erb
step2.html.erb
step3.html.erb
step4.html.erb
Ultra Light & Maintainable Wizard
ModelController
CreateShow
Step 1 PresenterValidations/Step Logic
Step 2 PresenterValidations/Step Logic
Step 3 PresenterValidations/Step Logic
ModelActiveRecord
Core Validations & Shared Logic
Step 4 PresenterValidations/Step Logic
Update & Redirect to Edit
Model PartController
EditUpdate
Ultra Light & Maintainable Wizard
• In a Nutshell:o Model resource
o Nested model part resource
(e.g. /projects/project1/project_parts/basic_info)
• Step name serves as ID
• Contains validations and before/after hooks for stepping
o Controller for the model resource:
• Begins wizard by creating model ActiveRecord
• Shows produced model at the end of the wizard
o Controller for the model part resource:
• Every step represents an Edit action of a model part
• Every step submission represents an Update action of a model part
o View for model resource show page
o View for every model part presenter edit page
Review• Why Use A Wizard?
• Wizard Example
• Wizard Implementation Goals
• 1001 Wizard Implementations
• Ultra Light & Maintainable Wizard