Created
November 17, 2022 10:55
-
-
Save bassemawhoob/f0356faaafa239e085fbecc5ffe73dfd to your computer and use it in GitHub Desktop.
Production S3 to local ActiveStorage on Rails
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Reference: https://dev.to/lucaskuhn/syncing-files-from-aws-s3-to-local-storage-on-rails-3639 | |
# Main goal: Sync a specific model's S3 images locally to have productions images working in development | |
# Assuming I have a model called `ProductImage` with an attachment called `artwork` | |
s3_bucket = "YOUR_S3_BUCKET" | |
access_key_id = Rails.application.credentials.dig(:aws, :access_key_id) | |
secret_access_key = Rails.application.credentials.dig(:aws, :secret_access_key) | |
storage_folder = Rails.root.join('storage') | |
storage_folder.mkpath | |
# For a specific model run the following loop or if you want to sync everything on S3 you can just run | |
# system("AWS_ACCESS_KEY_ID=#{access_key_id} AWS_SECRET_ACCESS_KEY=#{secret_access_key} aws s3 sync s3://#{s3_bucket} #{storage_folder}") | |
# instead of the loop | |
ProductImage.find_each do |product_image| | |
key = product_image.artwork.blob.key | |
system("AWS_ACCESS_KEY_ID=#{access_key_id} AWS_SECRET_ACCESS_KEY=#{secret_access_key} aws s3 sync s3://#{s3_bucket}/#{key} #{storage_folder}") | |
end | |
# Ignores sub_folders already created and .keep files | |
images = storage_folder.children.select { |file| file.file? && !file.empty? } | |
# Formats the file path of each image so ActiveStorage understands them using :local storage | |
images.each do |path_name| | |
dir, basename = path_name.split | |
file_name = basename.to_s | |
sub_folders = dir.join(file_name[0..1], file_name[2..3]) | |
sub_folders.mkpath # Create the subfolder used by active_record | |
path_name.rename(dir + sub_folders + basename) # Renames file to be moved into subfolder | |
end | |
# If we dumped the production data & restored it locally, all blobs will have a service_name `amazon`. | |
# We need to change this service name to `local` for rails to know where to fetch the blob from | |
ActiveStorage::Blob.update_all(service_name: "local") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment