How does Shrine S3 storage handle bucket versioning?

I have a bucket without versioning which I have used Shrine to upload files. I would like to enable versioning to prevent system admins from accidentally deleting anything, however I would like users to continue to delete objects permanently.

Is this a good place to add the S3 version_id to the file metadata?

class Uploader < Shrine

    plugin :add_metadata

    add_metadata do |io|

        if self.storage.class.name == 'Shrine::Storage::S3' && self.storage.bucket.versioning.status == 'Enabled'

            { 'version_id': self.storage.object(io.id).version_id }

        end

    end

end

Actually, on promote the version is not the same so I update the version_id after the file is promoted too…

class Attachment::PromoteJob < ApplicationJob

def perform(attacher_class, record_class, record_id, name, file_data)

attacher_class = Object.const_get(attacher_class)

record         = Object.const_get(record_class).find(record_id)

attacher = attacher_class.retrieve(model: record, name: name, file: file_data)

attacher.atomic_promote

if attacher.file.storage.class.name == 'Shrine::Storage::S3' && attacher.file.storage.bucket.versioning.status == 'Enabled'

  attacher.file.add_metadata("version_id" => attacher.file.storage.object(attacher.file.id).version_id)

  attacher.write

  attacher.record.save!

end

rescue Shrine::AttachmentChanged, ActiveRecord::RecordNotFound

# The attachment has changed or record has been deleted, nothing to do

end

end

Is there a DRYer way of doing this?

Actually need to set version_id also when bucket.versioning.status == ‘Suspended’ (i.e. version_id will return “null”)