We've moved discussions to Discord

ActsAsTenant::Errors::NoTenantSet with config.require_tenant = true

Rafik Mrabet
I have a Customer Devise user that belongs to a tenant. When I enabled config.require_tenant in the acts_as_tenant initializer and try to sign out as a Customer I'm getting:
ActsAsTenant::Errors::NoTenantSet in Customers::SessionsController#destroy
I'm not sure why is this happening. I've tried many things and still can't figure out the issue. I had to add the below to the Customers::SessionsController to make the new and create actions work but the destroy still doesn't:
class Customers::SessionsController < Devise::SessionsController
  set_current_tenant_through_filter
  before_action :set_tenant, only: [:new, :create, :destroy]
...
  private

  def set_tenant
    set_current_tenant(current_account)
  end
end
any suggestions on how to skip require_tenant for the destroy action since it's not relevant when signing out?
Rafik Mrabet
another strange behaviour, I'm using Doorkeeper in my app for OAuth 2.0. When I try to get an access token, I get this:
ActsAsTenant::Errors::NoTenantSet in Doorkeeper::TokensController#create

It really does not make sense why the tenant is required on the /oauth/token endpoint when it's irrelevant for this path. Why is config.require_tenant = true trying to enforce the presence of a tenant even on paths or actions that don't really need to know about it, like the destroy action to sign out a user and the create action for the token!!
Rafik Mrabet
Responding to my issue in case someone bumps into the same thing. It's worth mentioning that I am using the path /:account_id/ option for account switching, as per the Account Switching section of the docs here.

What fixed the first issue regarding the SessionsController, was to have prepend_before_action :set_tenant instead of before_action :set_tenant. I found the solution here.

However, regarding the wider issue of getting ActsAsTenant::Errors::NoTenantSet more generally where I don't expect it, I had to add the following line ActsAsTenant.current_tenant = Current.account in the account_middleware.rb, right below Current.account = account.
# /lib/jumpstart/lib/jumpstart/account_middleware.rb
...
    if (account = Account.find_by(id: account_id))
      Current.account = account
      ActsAsTenant.current_tenant = Current.account
    else
...
This ensures that the tenant is set whenever the /:account_id/ path is getting requested. As a result of this change, there is no need to have set_current_tenant_through_filter and prepend_before_action :set_tenant in the Devise sessions controller, nor in other controllers that might require the tenant to be set as a result of the the config.require_tenant = true configuration.

The reason I insisted on setting config.require_tenant = true is the make sure I do not run the risk of returning all records e.g. when having Project.all but the current_account is nil, as per the comment in the Multitenancy section of the docs here.
Rafik Mrabet I am running a similar setup as you, by using the path /:account_id/ option for account switching and config.require_tenant = true. For me the issue with the ActsAsTenant::Errors::NoTenantSet error being thrown happens also on the login page, as per definition i can not have a tenant set before the user logs in. 

How did you overcome this problem with devise and being able to show a login while requiring a tenant before the user has logged in to a tenant? 
Rafik Mrabet
hi Drazen, basically i have two types of users:
  1. the User model which isn't a tenant user, therefore it doesn't need a tenant to be set and shouldn't throw any errors when accessing /users/sign_in
  2. the Customer model which is a tenant user, therefore even the login page would require a tenant to be set in the path /:account_id/customers/sign_in
the latter still requires the tenant when the customer of a tenant logs in.
Rafik Mrabet
I have a Customer Devise user that belongs to a tenant. When I enabled config.require_tenant in the acts_as_tenant initializer and try to sign out as a Customer I'm getting:
ActsAsTenant::Errors::NoTenantSet in Customers::SessionsController#destroy
I'm not sure why is this happening. I've tried many things and still can't figure out the issue. I had to add the below to the Customers::SessionsController to make the new and create actions work but the destroy still doesn't:
class Customers::SessionsController < Devise::SessionsController
  set_current_tenant_through_filter
  before_action :set_tenant, only: [:new, :create, :destroy]
...
  private

  def set_tenant
    set_current_tenant(current_account)
  end
end
any suggestions on how to skip require_tenant for the destroy action since it's not relevant when signing out?
Rafik Mrabet
another strange behaviour, I'm using Doorkeeper in my app for OAuth 2.0. When I try to get an access token, I get this:
ActsAsTenant::Errors::NoTenantSet in Doorkeeper::TokensController#create

It really does not make sense why the tenant is required on the /oauth/token endpoint when it's irrelevant for this path. Why is config.require_tenant = true trying to enforce the presence of a tenant even on paths or actions that don't really need to know about it, like the destroy action to sign out a user and the create action for the token!!
Rafik Mrabet
Responding to my issue in case someone bumps into the same thing. It's worth mentioning that I am using the path /:account_id/ option for account switching, as per the Account Switching section of the docs here.

What fixed the first issue regarding the SessionsController, was to have prepend_before_action :set_tenant instead of before_action :set_tenant. I found the solution here.

However, regarding the wider issue of getting ActsAsTenant::Errors::NoTenantSet more generally where I don't expect it, I had to add the following line ActsAsTenant.current_tenant = Current.account in the account_middleware.rb, right below Current.account = account.
# /lib/jumpstart/lib/jumpstart/account_middleware.rb
...
    if (account = Account.find_by(id: account_id))
      Current.account = account
      ActsAsTenant.current_tenant = Current.account
    else
...
This ensures that the tenant is set whenever the /:account_id/ path is getting requested. As a result of this change, there is no need to have set_current_tenant_through_filter and prepend_before_action :set_tenant in the Devise sessions controller, nor in other controllers that might require the tenant to be set as a result of the the config.require_tenant = true configuration.

The reason I insisted on setting config.require_tenant = true is the make sure I do not run the risk of returning all records e.g. when having Project.all but the current_account is nil, as per the comment in the Multitenancy section of the docs here.
Rafik Mrabet I am running a similar setup as you, by using the path /:account_id/ option for account switching and config.require_tenant = true. For me the issue with the ActsAsTenant::Errors::NoTenantSet error being thrown happens also on the login page, as per definition i can not have a tenant set before the user logs in. 

How did you overcome this problem with devise and being able to show a login while requiring a tenant before the user has logged in to a tenant? 
Rafik Mrabet
hi Drazen, basically i have two types of users:
  1. the User model which isn't a tenant user, therefore it doesn't need a tenant to be set and shouldn't throw any errors when accessing /users/sign_in
  2. the Customer model which is a tenant user, therefore even the login page would require a tenant to be set in the path /:account_id/customers/sign_in
the latter still requires the tenant when the customer of a tenant logs in.
Notifications
You’re not receiving notifications from this thread.
© 2022 Jumpstart Pro by GoRails, LLC