Open davidlowry opened 4 years ago
Also running into a similar problem:
The model has an attachment using ActiveStorage
class Client < ApplicationRecord
has_one_attached :logo
end
The model is excluded like so:
Apartment.configure do |config|
...
config.excluded_models = ['Client']
...
end
When switched onto a tenant DB, the logo is not available.
$ Apartment::Tenant.switch('foo') { Client.first.logo.attached? } # = false
When accessing from the public DB, the logo is attached.
$ Apartment::Tenant.switch { Client.first.logo.attached? } # = true
Is there a way to make ActiveStorage play nice with Apartment?
Update: I was able to get things working by adding these two models to excluded_models
:
config.excluded_models = ['Client', 'ActiveStorage::Attachment', 'ActiveStorage::Blob']
But this obviously means all ActiveStorage data is only on the "public" DB.
I was wondering why purge_later
didn’t work on my ActiveStorage objects! They are running outside of the Apartment::Tenant scope of course. Thanks!
In my app, some attachments should be tenanted and other should be public. User avatars for example should be public but attachments on tenanted resources should be tenanted. There's an inherent incompatibility between schemas and polymorphism. It should still work if you use Apartment::Tenant.switch
at the right times, but it doesn't.
If I call resource.reload
in my avatar helper, that ensures that resource.avatar.attached?
is correct and consistent, but it also introduces an N+1. I'm not sure why, but this isn't working:
def avatar_url(resource, width)
Apartment::Tenant.switch("public") do
if resource.avatar.attached?
size_str = "#{width}x#{width}"
full_url_for_avatar(
resource.avatar.variant(resize: size_str)
)
else
""
end
end
end
While this is working:
def avatar_url(resource, width)
Apartment::Tenant.switch("public") do
# NOTE ActiveStorage + Apartment is buggy?
if resource.avatar.attached? || resource.reload.avatar.attached?
size_str = "#{width}x#{width}"
full_url_for_avatar(
resource.avatar.variant(resize: size_str)
)
else
""
end
end
end
This may have something to do with the way I'm including the attachment blob in the ActiveRecord::Relation but I don't see any issue with includes(user: { avatar_attachment: :blob })
.
Feature request, or How To??
Steps to reproduce
Have an excluded model, add ActiveStorage to that model. Here, Teams have "Logos" and "Branded Backgrounds" which are, ideally, global. My Teams also act as the Tenants here, but the fixture list can be global, and the issue may stand alone.
config.excluded_models = %w{ User Order Team Fixture }
I've tried to exclude some variation of
ActiveStorage
/ActiveStorage::Attached
/ActiveStorage::Attached::One
but get aundefined method
establish_connection' for [x]` in response.Desired behavior
A Tenanted model's attachments should be globally accessible
Actual behavior
While the Tenant model is visible, adding an attachment either in the public domain or in a tenant, it displays no attachments for each of the other tenants. If this was Paperclip or some such I don't imagine there'd be an issue, but using Rail's Own Brand storage solution I can't work out the solution.
System configuration
Ruby 2.6.3 Rails 5.2 Apartment 2.2 DB: Sqlite locally/Mysql in production test
config/initializers/apartment.rb
or so):`Apartment.configure do |config|
config.excluded_models = %w{ User Order Team Fixture }
config.excluded_models << 'ActiveStorage::Attached::One'
config.tenant_names = lambda { Team.clients.pluck :tenant_identifier }
config.use_schemas = true end`