Add task for ContentConfig image migration

This commit is contained in:
Maikel Linke
2022-04-05 13:22:48 +10:00
parent 1c1f9d73a3
commit 9dc3c5a06c
3 changed files with 81 additions and 3 deletions

View File

@@ -5,6 +5,10 @@ module Spree
class FileConfiguration < Configuration
def self.preference(name, type, *args)
if type == :file
# Active Storage blob id:
super "#{name}_blob_id", :integer, *args
# Paperclip attachment attributes:
super "#{name}_file_name", :string, *args
super "#{name}_content_type", :string, *args
super "#{name}_file_size", :integer, *args
@@ -17,7 +21,12 @@ module Spree
def get_preference(key)
if !has_preference?(key) && has_attachment?(key)
# Call Paperclip's attachment method:
public_send key
elsif key.ends_with?("_blob")
# Find referenced Active Storage blob:
blob_id = super("#{key}_id")
ActiveStorage::Blob.find_by(id: blob_id)
else
super key
end
@@ -37,7 +46,11 @@ module Spree
# errors if respond_to? isn't correct, so we override it here.
def respond_to?(method, include_all = false)
name = method.to_s.delete('=')
super(self.class.preference_getter_method(name), include_all) || super(method, include_all)
reference_name = "#{name}_id"
super(self.class.preference_getter_method(name), include_all) ||
super(reference_name, include_all) ||
super(method, include_all)
end
def has_attachment?(name)

View File

@@ -14,6 +14,25 @@ namespace :from_paperclip_to_active_storage do
end
end
# We have a special class called ContentConfiguration which is not a model
# and therfore can't use the normal Active Storage magic.
#
# It uses `Spree::Preference`s to store all the Paperclip attributes. These
# files are stored locally and we can replace them with preferences pointing
# to an Active Storage blob.
desc "Associate ContentConfig to ActiveStorage blobs"
task copy_content_config: :environment do
[
:logo,
:logo_mobile,
:logo_mobile_svg,
:home_hero,
:footer_logo,
].each do |name|
migrate_content_config_file(name)
end
end
def migrate_model(model)
duplicated_attachment_names(model).each do |name|
migrate_attachment(model, name)
@@ -71,6 +90,23 @@ namespace :from_paperclip_to_active_storage do
)
end
def migrate_content_config_file(name)
paperclip = ContentConfig.public_send(name)
return if ContentConfig.public_send("#{name}_blob_id")
return if paperclip.path.blank? || !paperclip.exists?
blob = ActiveStorage::Blob.create_and_upload!(
io: File.open(paperclip.path),
filename: paperclip.original_filename,
content_type: paperclip.content_type,
identify: false,
)
ContentConfig.public_send("#{name}_blob_id=", blob.id)
puts "Copied #{name}"
end
def duplicated_attachment_names(model)
paperclip_attachments = model.attachment_definitions.keys.map(&:to_s)
active_storage_attachments = model.attachment_reflections.keys

View File

@@ -31,7 +31,7 @@ describe "from_paperclip_to_active_storage.rake" do
end
describe ":migrate" do
it "creates Active Storage records for existing images on disk" do |example|
it "creates Active Storage records for existing images on disk" do
image = Spree::Image.create!(attachment: file)
image.attachment_attachment.delete
image.attachment_blob.delete
@@ -43,7 +43,7 @@ describe "from_paperclip_to_active_storage.rake" do
}.to(true)
end
it "creates Active Storage records for existing images on disk" do |example|
it "creates Active Storage records for images on AWS S3" do
attachment_definition = Spree::Image.attachment_definitions[:attachment]
allow(Spree::Image).to receive(:attachment_definitions).and_return(
attachment: attachment_definition.merge(s3_config)
@@ -74,6 +74,35 @@ describe "from_paperclip_to_active_storage.rake" do
end
end
describe ":copy_content_config" do
it "doesn't copy default images" do
run_task "from_paperclip_to_active_storage:copy_content_config"
expect(ContentConfig.logo_blob).to eq nil
end
it "copies uploaded images" do
ContentConfig.logo = file
ContentConfig.logo.save
run_task "from_paperclip_to_active_storage:copy_content_config"
expect(ContentConfig.logo_blob).to be_a ActiveStorage::Blob
end
it "doesn't copy twice" do
ContentConfig.logo = file
ContentConfig.logo.save
expect {
run_task "from_paperclip_to_active_storage:copy_content_config"
run_task "from_paperclip_to_active_storage:copy_content_config"
}.to change {
ActiveStorage::Blob.count
}.by(1)
end
end
def run_task(name)
Rake::Task[name].reenable
Rake.application.invoke_task(name)