From 4c7e947738d802672097bee97369ed9e64e4db95 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 4 May 2023 01:31:20 +0100 Subject: [PATCH] Migrate data So it turns out all images uploaded before the ActiveStorage migration are internally set to "public-read", and all images uploaded after the migration are internally set to "private". This migration switches all images in S3 buckets back to "public-read". --- db/migrate/20230504001141_public_images.rb | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 db/migrate/20230504001141_public_images.rb diff --git a/db/migrate/20230504001141_public_images.rb b/db/migrate/20230504001141_public_images.rb new file mode 100644 index 0000000000..ea0695f67b --- /dev/null +++ b/db/migrate/20230504001141_public_images.rb @@ -0,0 +1,40 @@ +require 'aws-sdk-s3' + +class PublicImages < ActiveRecord::Migration[7.0] + def up + return unless s3_bucket + + check_connection! + set_objects_to_readable + + ActiveStorage::Blob. + where(service_name: "amazon"). + where("content_type LIKE 'image/%'"). + update_all(service_name: "amazon_public") + end + + def down + ActiveStorage::Blob. + where(service_name: "amazon_public"). + where("content_type LIKE 'image/%'"). + update_all(service_name: "amazon") + end + + private + + # Returns an Aws::S3::Bucket object + def s3_bucket + @s3_bucket ||= ActiveStorage::Blob.where(service_name: "amazon").first&.service&.bucket + end + + # Checks bucket status. Throws an error if connection fails + def check_connection! + s3_bucket.exists? + end + + # Sets bucket objects' ACL to "public-read". Performs batched processing internally + # with a custom enumerator, see AWS::Resources::Collection#each for details. + def set_objects_to_readable + s3_bucket.objects.each{|object| object.acl.put(acl: "public-read") } + end +end