Skip to content
This repository has been archived by the owner on Oct 17, 2022. It is now read-only.

Driftrock/form_journey

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

48 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

#form_journey

Readme up-to-date for version '0.3.0'

gem 'form_journey'

Include the FormJourney::Controller module to any Rails controller to create a multi page form.

class UserSignupController < ApplicationController
  include FormJourney::Controller
  steps :signup, :personal, :additional_information

  def signup
    when_post do
      redirect_to next_step_path
    end
  end

  def personal
  end

  def additional_information
  end

  private

  def user_params
    # Any value in the "post" params will be included on the "journey_params" and kept in session
    journey_params.require(:user).permit(:name, :email)
  end
end

###Single Model form journey

When using a single model on the form journey there is a helper module

class UserSignupController < ApplicationController
  include FormJourney::Controller
  include FormJourney::UsesSingleModel
  steps :signup, :personal, :additional_information
  model_class User # also accepts a string representation of the constant
  params_method :user_params # also accepts a block

  private

  def user_params
    # Any value in the "post" params will be included on the "journey_params" and kept in session
    journey_params.require(:user).permit(:name, :email)
  end
end

This automatically creates an edit route and a helper method for getting the current model instance based on the user params. The method to retrieve the model instance is based on an underscored version of the model name:

model_class User #=> helper_method :user
model_class MyUser #=> helper_method :my_user
model_class Admin::MyUser #=> helper_method :admin_my_user

####Scoping

Often you'll want to scope the model used to be specific to the current user, rather than overwriting the model access methods you can define a model_scope:

class UserSignupController < ApplicationController
  include FormJourney::Controller
  include FormJourney::UsesSingleModel
  steps :signup, :personal, :additional_information
  model_class User # also accepts a string representation of the constant

  model_scope proc { |model_class| model_class.for_company(current_company) }

  params_method :user_params # also accepts a block

end

The proc runs in the context of the controller so it has access to any helper methods you may have defined for getting current session data.

It can also be defined by a chain of symbols when there are no parameters to pass, e.g:

model_class User
model_scope :enabled, :confirmed # => User.enabled.confirmed

The scope will be used both for retrieving an existing model during an edit and for creating a new model.

###Using journey parameters

# journey_params
# {
#   action: 'signup',
#   controller: 'user_signup',
#   user: {
#     name: 'John Smith',
#     email: '[email protected]'
#   }
# }

journey_params.get(:user) #=> { name: '...', email: '...' }
journey_params.get(:user, :name) #=> John Smith
journey_params.get(:user, :email) #=> '[email protected]'
journey_params.get(:user, :address) #=> nil
journey_params.get(:user, :image, :url) #=> nil

journey_params.del(:user, :name) #=> 'John Smith'
journey_params.del(:user, :address) #=> nil

journey_params.set(:user, :address, value: 'Regent Street')

journey_params.require(:user).permit(:name, :email) #=> { user: { name: '...', email: '...' } }

journey_params.add_to_array(:user, :phone_numbers, value: '001') #=> ['001']
journey_params.add_to_array(:user, :phone_numbers, value: '002') #=> ['001', '002']
journey_params.add_to_array(:user, :phone_numbers, value: '002', unique: true) #=> ['001', '002']
journey_params.add_to_array(:user, :phone_numbers, value: '002') #=> ['001', '002', '002']
journey_params.remove_from_array(:user, :phone_numbers, value: '002') #=> ['001']

# To clear the params
journey_params.clear!

###Changing steps You can change steps for a controller instance and update the journey. We suggest you do so with a before_action.

class UserSignupController < ApplicationController
  include FormJourney::Controller
  steps :signup, :personal, :additional_information
  
  before_action :add_extra_step
  
  protected
  
  def add_extra_step
    if unknow_referer?
      add_step(:referer)
      # You can also add the step before a existing one
      # add_step(:referer, before: :additional_information)
    end
  end

end

###Routes Define journey routes using the mount_journey method.

mount_journey 'user_signup', :user_signup

user_signup_step_path(:personal) #=> '/user_signup/personal'

Mount can also take a block

mount_journey 'user_signup', :user_signup do
  get '/confirm_email', to: 'user_signup#confirm_email'
end