acts_as_tenant icon indicating copy to clipboard operation
acts_as_tenant copied to clipboard

Removing all Tenant Models

Open aximuseng opened this issue 3 years ago • 7 comments

Can you return all the models that are active in the Tenant?

I am looking to have active_admin 'wipe' a tenant and override all callbacks (had_many and ancestry restrictions) etc.

aximuseng avatar May 20 '21 03:05 aximuseng

That's not really in the scope of this gem. You'd just need to delete all the records yourself. As long as the current_tenant is set, you can delete_all on the models probably.

excid3 avatar May 20 '21 14:05 excid3

To clarify I mean like the functionality Searchkick has:

Searchkick.models.each do |model| puts "Reindexing #{model.name} on #{tenant.tenant_name}" model.reindex end

It knows which models there are indexes on.

aximuseng avatar May 20 '21 15:05 aximuseng

ActsAsTenant doesn't keep track of what models you have scoped anywhere.

excid3 avatar May 20 '21 15:05 excid3

Ok - was just hoping there was a quick method like Searchkick has. I even looked in the source code for SK trying to figure out how that method works and apply that in AAT - no luck so far.

I am guessing there is nothing past Model.account.present? to test each model and confirm it has a tenant. Looking to ensure I don't orphan a ton of records each time I destroy a tenant.

aximuseng avatar May 20 '21 16:05 aximuseng

@aximuseng did you figure out any convenient solution for this? I ended up just adding a has_many reference for every tenant models with dependent: :destroy, but it's somewhat error prone.

drj17 avatar Jul 22 '21 16:07 drj17

I never got past this post and my efforts stalled. That is probably a good starting point. As you mentioned the potential for errors / disaster is there. In my case I have some pretty complex relationships and while testing various solutions I ran into issues where unless I have the tenant models destroyed in a very specific order it throws foreign key errors etc.

It feels like that scene from Apollo 13 where ground back-up team is trying to engineer the perfect sequence in the simulator and power-up the spacecraft without overloading the battery 🤣🚀

aximuseng avatar Jul 22 '21 16:07 aximuseng

I do think Chris is right, it's not the job of this gem to do that. Apartment has a .drop method but that's a little different due to its schema based approach.

I am glad this was brought up though, as it’s been somewhat challenging to find the right way to do this while maintaining data integrity, and ensuring no other tenant data is deleted.

Dependent: destroy Not advised because it instantiates all the children. We have 93 models attached to a tenant. I killed the box deleting a site.

Dependent: destroy_async This was introduced in rails 6, and from what I can tell wipes the foreign key and leaves them orphaned which can cause app errors while the end user waits for the records to be deleted.

Bypassing rails with on_delete :cascade (postgresql) This means leaving the rails ecosystem and adding an on_delete :cascade fk reference to each of the 93 tables. This just makes me queasy because I prefer to keep things in Rails. There’s the potential for error here because it wont delete any grandchildren from the children.

dependent: :delete_all The chaining here is an issue. Consider a Site has many orders, then orders has_many items. You'd get a fk reference error, which to fix means running dependent: :delete_all on the order to the items. This would then involve update every single model that has children to this method, which isn't great if you have callbacks or cleanup methods from after destroy callbacks on the model.

At the end of the day, there's no great way to do this, so it comes down to, which way sucks less?

What I'm starting to lean towards is something like destroy_async, but since we're on Rails 5 we'll have to write our own logic.

bearded-avenger avatar Aug 26 '21 15:08 bearded-avenger