DEV Community

Khairi Adnan
Khairi Adnan

Posted on

Extend Rails ActiveStorage disk service for multitenant

If you using Apartment and use ActiveStorage disk as a storage service, you might want to organise storage folder per-tenant or something like this:

storage/tenant1/
storage/tenant2/
storage/other_tenant/

This can be achieved by extending the default ActiveStorage disk service class

# lib/active_storage/service/tenant_service.rb
# extend disk service
require "active_storage/service/disk_service"

module ActiveStorage
  class Service::TenantService < Service::DiskService 
    def path_for(key) 
      current_tenant = Apartment::Tenant.current
      File.join root, current_tenant, folder_for(key), key
    end
  end
end

Change storage config for local using new service previously created

# config/storage.yml
test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

local:
  service: Tenant
  root: <%= Rails.root.join("storage") %>

** Don't forget to restart rails server

Benefits:

  • Easy to cleanup storage when tenant dropped
Apartment::Tenant.drop('tenant_name')
`rm -rf storage/tenant_name`
  • check disk usage per tenant
  • per tenant backup?

Discussion (2)

Collapse
mgharbik profile image
Gharbi Mohammed • Edited on

Hey Adnan, thanks for the post, for S3 service I just solved it this way:

# lib/active_storage/service/tenant_s3_service.rb
# extend s3 service
require 'active_storage/service/s3_service'

module ActiveStorage
  class Service::TenantS3Service < Service::S3Service
    private

    def object_for(key)
      current_tenant = Apartment::Tenant.current
      bucket.object File.join(current_tenant, key)
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

Then:

amazon:
  service: TenantS3
Enter fullscreen mode Exit fullscreen mode
Collapse
mkhairi profile image
Khairi Adnan Author

That awesome 🤩 !