(03-11-2021) On Rails > 6.1.4.1, using active_storage > 6.1.4.1 and within:
Gemfile:
gem 'azure-storage-blob', github: 'Azure/azure-storage-ruby'
config/environments/production.rb
# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :mirror #:microsoft or #:amazon
config/storage.yml:
amazon:
service: S3
access_key_id: XXX
secret_access_key: XXX
region: XXX
bucket: XXX
microsoft:
service: AzureStorage
storage_account_name: YYY
storage_access_key: YYY
container: YYY
mirror:
service: Mirror
primary: amazon
mirrors: [ microsoft ]
This does NOT work:
ActiveStorage::Blob.find_each do |blob|
blob.mirror_later
end && puts("Mirroring done!")
What DID work is:
ActiveStorage::Blob.find_each do |blob|
ActiveStorage::Blob.service.try(:mirror, blob.key, checksum: blob.checksum)
end && puts("Mirroring done!")
Not sure why that is, maybe future versions of Rails support it, or it needs additional background job setup, or it would have happened eventually (which never happened for me).
TL;DR
If you need to do mirroring for your entire storage immediately, add this rake task and execute it on your given environment with bundle exec rails active_storage:mirror_all
:
lib/tasks/active_storage.rake
namespace :active_storage do
desc 'Ensures all files are mirrored'
task mirror_all: [:environment] do
ActiveStorage::Blob.find_each do |blob|
ActiveStorage::Blob.service.try(:mirror, blob.key, checksum: blob.checksum)
end && puts("Mirroring done!")
end
end
Optional:
Once you mirrored all the blobs, then you probably want to change all their service names if you want them to actually get served from the right storage:
namespace :active_storage do
desc 'Change each blob service name to microsoft'
task switch_to_microsoft: [:environment] do
ActiveStorage::Blob.find_each do |blob|
blob.service_name = 'microsoft'
blob.save
end && puts("All blobs will now be served from microsoft!")
end
end
Finally, change: config.active_storage.service=
in production.rb or make the primary mirror to be the one you want future uploads to go to.
config.active_storage.service = :mirror
indevelopment.rb
or whatever env you want – Wedded