Class: OnlineMigrations::DataMigrations::SplitSharedAmazonContentSpecRows
- Inherits:
-
OnlineMigrations::DataMigration
- Object
- OnlineMigrations::DataMigration
- OnlineMigrations::DataMigrations::SplitSharedAmazonContentSpecRows
- Defined in:
- lib/online_migrations/data_migrations/split_shared_amazon_content_spec_rows.rb
Overview
Clones every shared free-text Amazon content spec row so each item owns
its own. Idempotent: rows already on a single item are skipped.
Background:
These tokens hold per-item marketing copy, but the nightly consolidator
collapsed rows whose text coincided across items. amazon_title_ differentiation was the worst case — 33 of 64 rows shared, covering 460
items, one row shared by 43. While shared, editing one item's copy
silently rewrites every co-tenant's, which is how a single edit to one
towel-warmer's Item Highlight overwrote a sibling SKU's English text on
2026-08-04.
Retiring the consolidator (#1856) stopped NEW sharing but deliberately
left the already-merged rows in place — this migration unpicks them.
It does not set legacy_do_not_merge (renamed from do_not_merge in
#1863): the flag lost its only reader when the consolidator went and the
write helper no longer sets it, so writing it here would be noise on a
column whose name now says it is on the way out.
Only free-text marketing tokens are split. Enum-ish attributes
(amazon_mounting_type, amazon_heating_method_1, …) legitimately share
a row — dozens of items really do all read "Embedded" — and cloning those
would add rows without removing any risk, since a correction there is
meant to apply to the whole set.
Recovery, if a render refresh is lost:
The split and the refresh are not atomic — the refresh is enqueued after
commit, and ItemAttributeWorker runs under the global retry: 0, so a
dispatch or worker failure leaves a split row with a stale
rendered_product_specifications. Re-running this migration will NOT
catch it, because the row is no longer shared and drops out of
#shared_spec_ids. Rendered specs are derived data, so the fix is simply
to re-render the affected items — safe to run at any time:
Item.joins(:product_specifications)
.where(product_specifications: { token: OnlineMigrations::DataMigrations::
SplitSharedAmazonContentSpecRows::TOKENS })
.distinct.find_each(&:update_rendered_product_specifications)
Persisting per-item refresh state was considered and rejected: this is a
one-shot backfill, and the recovery above is cheaper than the bookkeeping.
Defined Under Namespace
Classes: Item, ProductSpecification
Constant Summary collapse
- BATCH_SIZE =
Spec rows are heavy on callbacks (translations, render refresh
enqueue), so keep batches small. 25- TOKENS =
Free-text, per-item Amazon marketing copy. Stored as strings to match
theproduct_specifications.tokencolumn type at query time. %w[ amazon_title_differentiation amazon_title amazon_description amazon_generic_keyword amazon_feature_1 amazon_feature_2 amazon_feature_3 amazon_feature_4 amazon_feature_5 ].freeze
Instance Method Summary collapse
-
#collection ⇒ ActiveRecord::Batches::BatchEnumerator
Yields batches of shared Amazon content spec rows.
-
#count ⇒ Integer
Number of shared spec rows queued for splitting.
-
#process(specs) ⇒ void
Splits each spec in the batch into per-item rows.
Instance Method Details
#collection ⇒ ActiveRecord::Batches::BatchEnumerator
Yields batches of shared Amazon content spec rows.
99 100 101 |
# File 'lib/online_migrations/data_migrations/split_shared_amazon_content_spec_rows.rb', line 99 def collection ProductSpecification.where(id: shared_spec_ids).in_batches(of: BATCH_SIZE) end |
#count ⇒ Integer
Number of shared spec rows queued for splitting. Used by
online_migrations for progress reporting.
120 |
# File 'lib/online_migrations/data_migrations/split_shared_amazon_content_spec_rows.rb', line 120 def count = shared_spec_ids.size |
#process(specs) ⇒ void
This method returns an undefined value.
Splits each spec in the batch into per-item rows. Idempotent: a spec
that already has a single item is a no-op.
111 112 113 |
# File 'lib/online_migrations/data_migrations/split_shared_amazon_content_spec_rows.rb', line 111 def process(specs) specs.find_each { |spec| split_spec(spec) } end |