I'm using shrine gem for storing images in S3 by Ruby on Rails.
How can I make shrine behave as follows?
1. When uploading files from Frontend, they are stored in S3.
2. When deleting files from Frontend, they are deleted from Database, "but not deleted from S3"
That is, once I upload images in S3, they never be deleted by users' actions.
I found similar question, but what I want to realize is quite the opposite condition.
The present condition is like this.
I mounded shrine to ImageUploader in accordance with shrine S3 docs.
When uploading file, they are stored in S3. And when I try to delete files from Database, they are also deleted from S3.
This is the code block which uploads files to S3 and deletes from S3.
config/initializers/shrine.rb
require "shrine"
require "shrine/storage/file_system"
require "shrine/storage/s3"
s3_options = {
access_key_id: ENV[ACCESS_KEY_ID],
secret_access_key: ENV[SECRET_ACCESS_KEY],
region: ENV[REGION],
bucket: ENV[BUCKET],
}
Shrine.storages = {
cache: Shrine::Storage::S3.new(prefix: ..., **s3_options),
store: Shrine::Storage::S3.new(prefix: ..., **s3_options),
}
Shrine.plugin :activerecord
Shrine.plugin :cached_attachment_data
Shrine.plugin :restore_cached_data
Shrine.plugin :url_options,
cache: { public: true, host: ENV[CLOUDFRONT_URL] },
store: { public: true, host: ENV[CLOUDFRONT_URL] }
On ImageUploader < Shrine
, set resize logics. And on Photo
model, mount the uploader like include ImageUploader::Attachment(:image)
When deleting files from Database, I used ActiveRecord like this.(on this point, they are also deleted from S3)
class PhotoController < ApiController
def destroy
photo = Photo.find(params[:id])
photo.destroy!
render json: photo, serializer: PhotoSerializer
end
There are two ways you can achieve what you want.
Method 1: Skip ActiveRecord callbacks that trigger Shrine's callbacks by using delete
instead of destroy
on your controller.
Method 2: Add mirroring and backup to your Shrine configuration like so
Shrine.storages = { cache: ..., store: ..., backup: ... }
Shrine.plugin :mirroring, mirror: { store: :backup }