class MovePromotionCodeToPromotionCodeValue < ActiveRecord::Migration def up # This is done via SQL for performance reasons. For larger stores it makes # a difference of minutes vs hours for completion time. say_with_time 'generating spree_promotion_codes' do Spree::Promotion.connection.execute(<<-SQL.strip_heredoc) insert into spree_promotion_codes (promotion_id, value, created_at, updated_at) select spree_promotions.id, spree_promotions.code, '#{Time.current.to_s(:db)}', '#{Time.current.to_s(:db)}' from spree_promotions left join spree_promotion_codes on spree_promotion_codes.promotion_id = spree_promotions.id where (spree_promotions.code is not null and spree_promotions.code <> '') -- promotion has a code and spree_promotion_codes.id is null -- a promotion_code hasn't already been created SQL end if Spree::PromotionCode.group(:promotion_id).having("count(0) > 1").exists? raise "Error: You have promotions with multiple promo codes. The migration code will not work correctly".squish end say_with_time 'linking order promotions' do Spree::Promotion.connection.execute(<<-SQL.strip_heredoc) update spree_orders_promotions set promotion_code_id = ( select spree_promotion_codes.id from spree_promotions inner join spree_promotion_codes on spree_promotion_codes.promotion_id = spree_promotions.id where spree_promotions.id = spree_orders_promotions.promotion_id ) where spree_orders_promotions.promotion_code_id is null SQL end say_with_time 'linking adjustments' do Spree::Promotion.connection.execute(<<-SQL.strip_heredoc) update spree_adjustments set promotion_code_id = ( select spree_promotion_codes.id from spree_promotion_actions inner join spree_promotions on spree_promotions.id = spree_promotion_actions.promotion_id inner join spree_promotion_codes on spree_promotion_codes.promotion_id = spree_promotions.id where spree_promotion_actions.id = spree_adjustments.source_id ) where spree_adjustments.source_type = 'Spree::PromotionAction' and spree_adjustments.promotion_code_id is null SQL end end def down # We can't do a down migration because we can't tell which data was created # by this migration and which data already existed. end end