Top Banner
Ultra Light & Maintainable Wizards in Rails Andy Maleh VP of Engineering BIG ASTRONAUT
46

Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Jul 16, 2015

Download

Technology

AndyMaleh
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Ultra Light & Maintainable

Wizards in RailsAndy Maleh

VP of Engineering

BIG ASTRONAUT

Page 2: 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

Page 3: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Why Use A Wizard?Avoid overwhelming user with a huge form

Page 4: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Why Use A Wizard?Simplify a workflow into multiple steps

Page 5: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Why Use A Wizard?Help the user by providing guidance

Page 6: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Wizard ExampleEarlyShares Project Idea Submission

Page 7: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Wizard ExampleStep 1 – Basic Info

Page 8: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Wizard ExampleStep 2 – Details

Page 9: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Wizard ExampleStep 3 – Document Content

Page 10: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Wizard ExampleStep 4 – Preview

Page 11: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Wizard ExampleSteps Done – Project Landing Page

Page 12: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

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

Page 13: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

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

Page 14: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

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

Page 15: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

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

Page 16: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

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

Page 17: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

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

Page 18: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

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

Page 19: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

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

Page 20: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

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

Page 21: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

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

Page 22: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

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”}

Page 23: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

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

Page 24: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

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

Page 25: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

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

Page 26: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Ultra Light & Maintainable Wizard

• Philosophy:o A wizard is simply a builder of a model

Page 27: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Ultra Light & Maintainable Wizard

• Philosophy:o Every step is simply a partial data-view of the model

Page 28: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Ultra Light & Maintainable Wizard

• Philosophy:o REST resources are the model and model parts edited during a step.

Page 29: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Ultra Light & Maintainable Wizard

• Philosophy:o Models must manage validations without conditions by relying on step-

polymorphism

Page 30: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

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

Page 31: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

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

Page 32: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

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

Page 33: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Ultra Light & Maintainable Wizard

Routes

Page 34: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Ultra Light & Maintainable Wizard

Model (main REST resource)

Page 35: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Ultra Light & Maintainable Wizard

Step Sub-Models aka Model Parts

Page 36: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Ultra Light & Maintainable Wizard

Project::BasicInfo Step Sub-Model

Page 37: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Ultra Light & Maintainable Wizard

Project::BasicInfo Step Sub-Model (cont’d)

Page 38: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Ultra Light & Maintainable Wizard

Project::Detail Step Sub-Model

Page 39: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Ultra Light & Maintainable Wizard

ProjectsController

Page 40: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

ProjectPartsController

Page 41: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Ultra Light & Maintainable Wizard

ProjectPartsController (cont’d)

Page 42: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Ultra Light & Maintainable Wizard

Views

Page 43: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Ultra Light & Maintainable Wizard

View form template

Page 44: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Ultra Light & Maintainable Wizard

Step View Template Example

Page 45: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

Review• Why Use A Wizard?

• Wizard Example

• Wizard Implementation Goals

• 1001 Wizard Implementations

• Ultra Light & Maintainable Wizard

Page 46: Ultra Light and Maintainable Rails Wizards at RailsConf 2014

github.com/AndyMaleh/ultra_light_wizard

Andy Maleh – VP of Engineering – Big Astronaut

• WEBSITE: http://www.bigastronaut.com

• BLOG: http://andymaleh.blogspot.com

• TWITTER: @AndyMaleh