Module: RailsOnboarding::Backfill
- Defined in:
- lib/rails_onboarding/backfill.rb
Overview
One-shot data fixes for applications that installed RailsOnboarding on top of an existing users table.
Users who signed up before the gem was installed have NULL onboarding
columns, so the admin reports them as "Not Started" and - depending on the
onboarding_required_for strategy - they can be pushed back through a flow
they have no business seeing. Backfilling marks them as already onboarded.
Everything here writes with update_all in batches: no callbacks, no
validations, and deliberately no analytics events. Backfilled users never
went through onboarding, so recording completion events for them would put
fiction into the funnel metrics.
Defined Under Namespace
Classes: Result
Constant Summary collapse
- DEFAULT_BATCH_SIZE =
1_000- REQUIRED_COLUMNS =
%w[ onboarding_completed onboarding_completed_at onboarding_current_step ].freeze
Class Method Summary collapse
-
.mark_existing_users_onboarded(created_before: nil, completed_at: Time.current, batch_size: DEFAULT_BATCH_SIZE, dry_run: false) ⇒ Result
Marks pre-existing users as having finished onboarding.
-
.pending_scope(created_before: nil) ⇒ Object
Users the backfill would touch.
- .user_class ⇒ Object
Class Method Details
.mark_existing_users_onboarded(created_before: nil, completed_at: Time.current, batch_size: DEFAULT_BATCH_SIZE, dry_run: false) ⇒ Result
Marks pre-existing users as having finished onboarding.
Only users who have never engaged with onboarding are touched: not completed, not skipped, and sitting on no current step. Anyone mid-flow is left alone so a backfill can be re-run safely while the app is live.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/rails_onboarding/backfill.rb', line 50 def mark_existing_users_onboarded(created_before: nil, completed_at: Time.current, batch_size: DEFAULT_BATCH_SIZE, dry_run: false) ensure_columns! scope = pending_scope(created_before: created_before) matched = scope.count return Result.new(matched: matched, updated: 0, dry_run: true) if dry_run updated = 0 scope.in_batches(of: batch_size) do |batch| updated += batch.update_all(completion_assignment(completed_at)) end Result.new(matched: matched, updated: updated, dry_run: false) end |
.pending_scope(created_before: nil) ⇒ Object
Users the backfill would touch. Exposed so callers can inspect or further narrow the set before running.
68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/rails_onboarding/backfill.rb', line 68 def pending_scope(created_before: nil) scope = user_class .where(onboarding_current_step: nil) .where(onboarding_completed: [ false, nil ]) scope = scope.where(onboarding_skipped: [ false, nil ]) if column?("onboarding_skipped") return scope unless created_before cutoff = normalize_time(created_before) scope.where("#{quoted_table}.created_at < ? OR #{quoted_table}.created_at IS NULL", cutoff) end |
.user_class ⇒ Object
80 81 82 |
# File 'lib/rails_onboarding/backfill.rb', line 80 def user_class RailsOnboarding.configuration.user_class_name.constantize end |