Migrate first master variant image to product image

(cherry picked from commit 21cba0aa13)
This commit is contained in:
Matt-Yorkley
2023-06-05 14:33:14 +01:00
committed by David Cook
parent 8e99f496ff
commit 86703bb545
4 changed files with 95 additions and 1 deletions

View File

@@ -0,0 +1,46 @@
class MigrateMasterImageToProduct < ActiveRecord::Migration[7.0]
def up
# Multiple images can be present per variant, ordered by the `position` column.
# In some cases if the image was deleted and another was added, the numbering can be off,
# so the positions of the images might be 3,4,5 or 2,3 and the "first" image would be position 2
# or position 3 in those cases (instead of 1).
#
# This finds the image for each variant with the lowest `position` out of the current images and
# sets it's `position` to 1 (if it's not already 1) to make it easier to operate on the "first" image.
renumber_first_image
# Switches the association of the first image for each master variant to it's product
migrate_master_images
end
def renumber_first_image
ActiveRecord::Base.connection.execute(<<-SQL
UPDATE spree_assets
SET position = '1'
FROM (
SELECT DISTINCT ON (viewable_id) id, viewable_id, position
FROM spree_assets
WHERE spree_assets.viewable_type = 'Spree::Variant'
ORDER BY viewable_id, position ASC
) variant_first_image
WHERE spree_assets.id = variant_first_image.id
AND spree_assets.position != '1'
SQL
)
end
def migrate_master_images
ActiveRecord::Base.connection.execute(<<-SQL
UPDATE spree_assets
SET viewable_type = 'Spree::Product',
viewable_id = spree_variants.product_id
FROM spree_variants
WHERE spree_variants.id = spree_assets.viewable_id
AND spree_variants.is_master = true
AND spree_variants.deleted_at IS NULL
AND spree_assets.viewable_type = 'Spree::Variant'
AND spree_assets.position = '1'
SQL
)
end
end

View File

@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2023_05_22_120633) do
ActiveRecord::Schema[7.0].define(version: 2023_06_03_181837) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_stat_statements"
enable_extension "plpgsql"

View File

@@ -0,0 +1,9 @@
# frozen_string_literal: true
FactoryBot.define do
factory :asset, class: Spree::Asset do
viewable { nil }
position { 1 }
type { "Spree::Image" }
end
end

View File

@@ -0,0 +1,39 @@
# frozen_string_literal: true
require 'spec_helper'
require_relative '../../db/migrate/20230603181837_migrate_master_image_to_product'
describe MigrateMasterImageToProduct do
subject { MigrateMasterImageToProduct.new }
let!(:product1) { create(:product) }
let!(:master1) { create(:variant, product: product1, is_master: true) }
let!(:image1) { create(:asset, viewable: master1, position: 1) }
let!(:image2) { create(:asset, viewable: master1, position: 2) }
let!(:product2) { create(:product) }
let!(:master2) { create(:variant, product: product2, is_master: true) }
let!(:image3) { create(:asset, viewable: master2, position: 2) }
let!(:image4) { create(:asset, viewable: master2, position: 3) }
let!(:image5) { create(:asset, viewable: master2, position: 4) }
describe "#renumber_first_image" do
it "updates the first image to position 1 if it's not already 1" do
subject.renumber_first_image
expect(image1.reload.position).to eq 1
expect(image3.reload.position).to eq 1
end
end
describe "#migrate_master_images" do
before { image3.update_columns(position: 1) }
it "migrates the master variant image to the product" do
subject.migrate_master_images
expect(product1.reload.image.id).to eq image1.id
expect(product2.reload.image.id).to eq image3.id
end
end
end