From 314ce70000701cfa25a8c0f43d96138696e74136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Fri, 7 Oct 2022 19:48:32 +0200 Subject: [PATCH] Use a different attachments folder per tenant While this is not strictly necessary, it can help moving the data of one tenant to a different server or removing it. Note we're using subfolders inside the `tenants` subfolder. If we simply used subfolders with the schema names, if the schema names were, for instance, language codes like `es`, `en`, `it`, ... they would conflict with the default subfolders used by Active Storage. --- config/storage.yml | 4 ++-- .../service/tenant_disk_service.rb | 13 +++++++++++++ spec/models/attachable_spec.rb | 16 ++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 lib/active_storage/service/tenant_disk_service.rb create mode 100644 spec/models/attachable_spec.rb diff --git a/config/storage.yml b/config/storage.yml index 590c3bb76..09c938b65 100644 --- a/config/storage.yml +++ b/config/storage.yml @@ -1,9 +1,9 @@ local: - service: Disk + service: TenantDisk root: <%= Rails.root.join("storage") %> test: - service: Disk + service: TenantDisk root: <%= Rails.root.join("tmp/storage") %> # s3: diff --git a/lib/active_storage/service/tenant_disk_service.rb b/lib/active_storage/service/tenant_disk_service.rb new file mode 100644 index 000000000..63414f295 --- /dev/null +++ b/lib/active_storage/service/tenant_disk_service.rb @@ -0,0 +1,13 @@ +require "active_storage/service/disk_service" + +module ActiveStorage + class Service::TenantDiskService < Service::DiskService + def path_for(key) + if Tenant.default? + super + else + super.sub(root, File.join(root, "tenants", Tenant.current_schema)) + end + end + end +end diff --git a/spec/models/attachable_spec.rb b/spec/models/attachable_spec.rb new file mode 100644 index 000000000..32b208bc8 --- /dev/null +++ b/spec/models/attachable_spec.rb @@ -0,0 +1,16 @@ +require "rails_helper" + +describe Attachable do + it "stores attachments for the default tenant in the default folder" do + file_path = build(:image).file_path + + expect(file_path).to include "storage/" + expect(file_path).not_to include "tenants" + end + + it "stores tenant attachments in a folder for the tenant" do + allow(Tenant).to receive(:current_schema).and_return("image-master") + + expect(build(:image).file_path).to include "storage/tenants/image-master/" + end +end