Code Monkey home page Code Monkey logo

wicked's Introduction

Wicked

Use wicked to make your Rails controllers into step-by-step wizards. To see Wicked in action check out the example Rails app or watch the screencast.

Why

Many times I'm left wanting a RESTful way to display a step by step process that may or not be associated with a resource. Wicked gives the flexibility to do what I want while hiding all the really scary stuff you shouldn't do in a controller to make this possible. At it's core Wicked is a RESTful(ish) state machine, but you don't need to know that, just use it.

Install

Add this to your Gemfile

  gem 'wicked'

Then run bundle install and you're ready to start

How

We are going to build an 'after signup' wizard. First create a controller:

  rails g controller after_signup

Add Routes into config/routes.rb:

  resources :after_signup

Next include Wicked::Wizard in your controller

  class AfterSignupController < ApplicationController
    include Wicked::Wizard

    steps :confirm_password, :confirm_profile, :find_friends
    # ...

You can also use the old way of inheriting from Wicked::WizardController.

  class AfterSignupController < Wicked::WizardController

    steps :confirm_password, :confirm_profile, :find_friends
    # ...

The wizard is set to call steps in order in the show action, you can specify custom logic in your show using a case statement like below. To send someone to the first step in this wizard we can direct them to after_signup_path(:confirm_password).

  class AfterSignupController < ApplicationController
    include Wicked::Wizard

    steps :confirm_password, :confirm_profile, :find_friends

    def show
      @user = current_user
      case step
      when :find_friends
        @friends = @user.find_friends
      end
      render_wizard
    end
  end

You'll need to call render_wizard at the end of your action to get the correct views to show up.

By default the wizard will render a view with the same name as the step. So for our controller AfterSignupController with a view path of /views/after_signup/ if call the :confirm_password step, our wizard will render /views/after_signup/confirm_password.html.erb

Then in your view you can use the helpers to get to the next step.

   <%= link_to 'skip', next_wizard_path %>

You can manually specify which wizard action you want to link to by using the wizard_path helper.

   <%= link_to 'skip', wizard_path(:find_friends) %>

In addition to showing sequential views we can update elements in our controller.

  class AfterSignupController < ApplicationController
    include Wicked::Wizard

    steps :confirm_password, :confirm_profile, :find_friends

    def update
      @user = current_user
      case step
      when :confirm_password
        @user.update_attributes(params[:user])
      end
      sign_in(@user, :bypass => true) # needed for devise
      render_wizard @user
    end
  end

We're passing render_wizard our @user object here. If you pass an object into render_wizard it will show the next step if the object saves or re-render the previous view if it does not save.

To get to this update action, you simply need to submit a form that PUT's to the same url

    <%= form_for @user, :url => wizard_path, :method => :put do |f| %>
      <%=  f.password_field :password  %>
      <%=  f.password_field :password_confirmation  %>

      <%= f.submit "Change Password" %>
    <% end %>

We explicitly tell the form to PUT above. If you forget this, you will get a warning about the create action not existing, or no route found for POST. Don't forget this.

In the controller if you find that you want to skip a step, you can do it simply by calling skip_step

  def show
    @user = current_user
    case step
    when :find_friends
      if @user.has_facebook_access_token?
        @friends = @user.find_friends
      else
        skip_step
      end
    end
    render_wizard
  end

Now you've got a fully functioning AfterSignup controller! If you have questions or if you struggled with something, let me know on twitter, and i'll try to make it better or make the docs better.

Quick Reference

View/URL Helpers

  wizard_path                  # Grabs the current path in the wizard
  wizard_path(:specific_step)  # Url of the :specific_step
  next_wizard_path             # Url of the next step

  # These only work while in a Wizard, and are not absolute paths
  # You can have multiple wizards in a project with multiple `wizard_path` calls

Controller Tidbits:

  steps  :first, :second       # Sets the order of steps
  step                         # Gets symbol of current step
  next_step                    # Gets symbol of next step
  render_wizard                # Renders the current step
  render_wizard(@user)         # Shows next_step if @user.save, otherwise renders current step

Finally:

Don't forget to create your named views

  app/
   views/
    controller_name/
      first.html.erb
      second.html.erb
      # ...

About

Please poke around the source code, if you see easier ways to get a Rails controller do do what I want, let me know.

If you have a question file an issue or, find me on the Twitters @schneems.

This project rocks and uses MIT-LICENSE.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.