Module: RailsOnboarding::ControllerHelpers

Extended by:
ActiveSupport::Concern
Defined in:
lib/rails_onboarding/controller_helpers.rb

Instance Method Summary collapse

Instance Method Details

#advance_onboarding!(step_name) ⇒ Boolean

Complete the current onboarding step from a host-app controller.

Call this from the action that performs the step's real work (e.g. ProfilesController#create after a successful save), then redirect to onboarding_path to advance the user:

if advance_onboarding!(:profile)
redirect_to onboarding_path
else
redirect_to @profile
end

Deliberately a no-op unless the named step is the user's current step - so when the same action runs outside onboarding (the user edits their profile again next week), the controller behaves normally.

Parameters:

  • step_name (Symbol, String)

    the step this action fulfills

Returns:

  • (Boolean)

    true if the step was completed and the user advanced



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/rails_onboarding/controller_helpers.rb', line 85

def advance_onboarding!(step_name)
  return false unless user_signed_in?
  return false unless current_user.respond_to?(:needs_onboarding?)
  return false unless current_user.needs_onboarding?

  step = current_user.current_onboarding_step
  return false unless step && step[:name].to_sym == step_name.to_sym

  current_user.complete_onboarding_step!(step[:name])
  true
end

#needs_onboarding?Boolean

Returns:

  • (Boolean)


29
30
31
32
33
34
35
36
# File 'lib/rails_onboarding/controller_helpers.rb', line 29

def needs_onboarding?
  return false unless user_signed_in?
  return false if on_onboarding_page?
  return false if skip_onboarding_request?
  return false if self.class.skip_onboarding_for_action?(action_name)

  current_user.needs_onboarding?
end

#on_onboarding_page?Boolean

Returns:

  • (Boolean)


38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/rails_onboarding/controller_helpers.rb', line 38

def on_onboarding_page?
  # Deliberately reads the engine proxy, not the onboarding_path method -
  # in engine controllers the engine's own url_helper shadows ours, so
  # relying on method resolution here would be ambiguous. Chomping makes
  # the match segment-aware: the engine root (with or without its
  # trailing slash) and anything under it count, but sibling host paths
  # that merely share the prefix (/onboarding_help when mounted at
  # /onboarding) do not.
  root = rails_onboarding.onboarding_path.chomp("/")
  return true if request.path == root || request.path.start_with?("#{root}/")

  on_current_step_page?
end

#onboarding_pathObject

The onboarding flow lives at the engine's mount root, so the raw engine helper returns it with a trailing slash ("/onboarding/") like any mounted engine root. Serve host apps the canonical slash-less form for links and redirects.



62
63
64
65
# File 'lib/rails_onboarding/controller_helpers.rb', line 62

def onboarding_path
  path = rails_onboarding.onboarding_path.chomp("/")
  path.empty? ? "/" : path
end

#resolve_onboarding_step_path(path) ⇒ Object

Resolve a step's :path option against the host application's routes. Symbols/Strings are sent to the main_app route proxy; Procs are instance_exec'd in the controller context, so a zero-arg lambda can use main_app, current_user, params, etc.:

path: :new_profile_path
path: -> { main_app.new_post_path(from: "onboarding") }


104
105
106
# File 'lib/rails_onboarding/controller_helpers.rb', line 104

def resolve_onboarding_step_path(path)
  path.is_a?(Proc) ? instance_exec(&path) : main_app.public_send(path)
end

#skip_onboarding_request?Boolean

Returns:

  • (Boolean)


52
53
54
55
56
# File 'lib/rails_onboarding/controller_helpers.rb', line 52

def skip_onboarding_request?
  request.xhr? ||
    request.format.json? ||
    request.path.start_with?("/api")
end