Class: OnlineMigrations::DataMigrations::BackfillReceptionTypeWildValues
- Inherits:
-
OnlineMigrations::DataMigration
- Object
- OnlineMigrations::DataMigration
- OnlineMigrations::DataMigrations::BackfillReceptionTypeWildValues
- Defined in:
- lib/online_migrations/data_migrations/backfill_reception_type_wild_values.rb
Overview
Cleans up the four "wild" reception-type values still on production
so the columns can move to a Postgres native enum type in a follow-up
PR without violations:
room_configurations.reception_type = 'MyProjects'(~2,325 rows)
→'IQ'('MyProjects' was the legacy name for what is now the
quote-builder / instant-quote flow)room_configurations.reception_type = 'Other'(~1,833 rows)
→'Unspecified'(semantic match — the row was never categorized)room_configurations.reception_type = ''(~2 rows)
→'Unspecified'(junk; the column is NOT NULL so empty string
is the closest thing to "missing")opportunities.opportunity_reception_type = ''(1 row)
→'CRM'(the column default —'Unspecified'is not a valid
opportunity reception type, only a room-configuration one)
All four values were ad-hoc literals from earlier eras of the codebase.
Cleanup mappings confirmed by the team (cbillen) on 2026-05-10.
Constant Summary collapse
- BATCH_SIZE =
Batch size — small enough to keep each transaction quick.
1_000- MAPPINGS =
Each entry is
[model, column, old_value, new_value]. The order
is informational; the four updates are independent. [ [::RoomConfiguration, :reception_type, 'MyProjects', 'IQ'], [::RoomConfiguration, :reception_type, 'Other', 'Unspecified'], [::RoomConfiguration, :reception_type, '', 'Unspecified'], [::Opportunity, :opportunity_reception_type, '', 'CRM'] ].freeze
Instance Method Summary collapse
-
#collection ⇒ Array<Array(Class, Symbol, String, String, Array<Integer>)>
Returns one
[model, column, old_value, new_value, ids]tuple per batch across every (model, column, old_value) combination. -
#count ⇒ Integer
Total un-migrated rows across all four mappings.
-
#process(batch) ⇒ void
Rewrites one batch from the wild value to the canonical replacement.
Instance Method Details
#collection ⇒ Array<Array(Class, Symbol, String, String, Array<Integer>)>
Returns one [model, column, old_value, new_value, ids] tuple
per batch across every (model, column, old_value) combination.
old_value is threaded through so process can use it in the
conditional WHERE without re-deriving it (two of the MAPPINGS
rows collapse to the same (model, column, new_value) key —
'Other' → 'Unspecified' and '' → 'Unspecified' — which
would make a MAPPINGS.find ambiguous).
Returned eagerly as an Array (not a streaming Enumerator)
because online_migrations' MigrationJob#build_enumerator
only handles ActiveRecord::Relation, BatchEnumerator, and
Array from #collection — a plain Enumerator raises
ArgumentError before on_start runs and leaves the row
wedged at status='enqueued'. The eager pass is cheap here:
the four mappings cover ~4.2k matching rows total, which
produces only ~6 tuples at BATCH_SIZE=1_000.
60 61 62 63 64 65 66 67 68 69 |
# File 'lib/online_migrations/data_migrations/backfill_reception_type_wild_values.rb', line 60 def collection batches = [] MAPPINGS.each do |model, column, old_value, new_value| model.where(column => old_value) .in_batches(of: BATCH_SIZE) do |batch| batches << [model, column, old_value, new_value, batch.ids] end end batches end |
#count ⇒ Integer
Total un-migrated rows across all four mappings. Drives the
online_migrations progress bar.
88 89 90 |
# File 'lib/online_migrations/data_migrations/backfill_reception_type_wild_values.rb', line 88 def count MAPPINGS.sum { |model, column, old_value, _| model.where(column => old_value).count } end |
#process(batch) ⇒ void
This method returns an undefined value.
Rewrites one batch from the wild value to the canonical replacement.
The conditional where(column => old_value) makes the write
idempotent — already-migrated rows are no-ops.
78 79 80 81 82 |
# File 'lib/online_migrations/data_migrations/backfill_reception_type_wild_values.rb', line 78 def process(batch) model, column, old_value, new_value, ids = batch model.where(id: ids, column => old_value) .update_all(column => new_value, updated_at: Time.current) end |