YOU ARE DOWNLOADING DOCUMENT

Please tick the box to continue:

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


Related Documents