We've moved discussions to Discord

Using Apartment instead of Acts_As_Tenant for multi tenancy - ActionCable connection issues

Brad Schwarzhoff
I'm modifying my Jumpstart application to be multi tenant and I'm using the Apartment gem instead of acts_as_tenant.  I understand the reasons for going with acts_as_tenant instead of apartment, but my client is looking for more separation of data between clients, and there is also less of a concern over performance because there will be a limited number of tenants.  There is also no model that is shared between the tenants (not even the Users model).

I have the application generally working with Apartment using different domains for each tenant. I'm running into a problem with ActionCable, where it's trying to access the "public" (aka default) schema to open the ActionCable connection instead of the correct Tenant.  The user is not found in the public schema, so I get the error below:

Started GET "/cable" for 127.0.0.1 at 2021-07-08 17:50:35 -0500
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2021-07-08 17:50:35 -0500
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
  [secure_forms_system_dev] [public]   User Load (1.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ app/channels/application_cable/connection.rb:19:in `find_verified_user'
An unauthorized connection attempt was rejected
Finished "/cable/" [WebSocket] for 127.0.0.1 at 2021-07-08 17:50:35 -0500

Since the connection is not open, any further calls to the ActionCable give me an error of:

The ActionCable connection is not open!

I'm pretty sure I need to modify the code in app/channels/application_cable/connection.rb and also the SetCurrentRequestDetails module (in app/controllers/concerns/,   and I'm hoping that someone  can point me in the right direction ( Chris Oliver   maybe?)  Thanks in advance for any help you could offer.

Best,
Brad

Chris Oliver
You'll need to modify the SetCurrentRequestDetails to set the Apartment tenant, as well as the ApplicationCable::Connection which must also do the same thing for websocket requests.

https://github.com/jumpstart-pro/jumpstart-pro/blob/master/app/channels/application_cable/connection.rb#L32

You'll basically just swap out 
ActsAsTenant.current_tenant = account 
with 
Apartment::Tenant.switch!(account)
Chris Oliver
Apparently I fiddled with this way back in 2017. 😜

https://github.com/influitive/apartment/issues/391#issuecomment-276483649
Brad Schwarzhoff
Thank you so much Chris Oliver !!  

In my case I'm using the full host to switch tenants, so I added this to the first line of the ApplicationCable::Connection.connect method and also in the the set_current_tenant method:

Apartment::Tenant.switch!(request.host)

That did the trick!  Thanks again, the land of middleware is foreign to me, but I'm learning ;)
Notifications
You’re not receiving notifications from this thread.