I am using ActsAsTenant, and I keep getting the error below on any Devise route (i.e. any Devise controller). It seems that Devise tries to get the current_user or something to do with getting a User before the tenant has been set, so ActsAsTenant then raises an error. I tried using a prepend_before_action to set the tenant but that didnt work.
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
prepend_before_action :secure_app
before_action :authenticate_user!
private
def secure_app
self.class.set_current_tenant_by_subdomain_or_domain
end
end
How do I make sure that the tenant is set before Devise starts looking for the current_user?
ActsAsTenant::Errors::NoTenantSet at /edit ActsAsTenant::Errors::NoTenantSet
block in User.acts_as_tenant
() home/lee/.rvm/gems/ruby-2.1.1/bundler/gems/acts_as_tenant-1b7d146d750b/lib/acts_as_tenant/model_extensions.rb, line 54
block (3 levels) in User.build_default_scope
activerecord (4.1.4) lib/active_record/scoping/default.rb, line 103
User::ActiveRecord_Relation#scoping
activerecord (4.1.4) lib/active_record/relation.rb, line 285
block (2 levels) in User.build_default_scope
activerecord (4.1.4) lib/active_record/scoping/default.rb, line 103
block in User.build_default_scope
activerecord (4.1.4) lib/active_record/scoping/default.rb, line 102
User.evaluate_default_scope
activerecord (4.1.4) lib/active_record/scoping/default.rb, line 125
User.build_default_scope
activerecord (4.1.4) lib/active_record/scoping/default.rb, line 101
User.default_scoped
activerecord (4.1.4) lib/active_record/scoping/named.rb, line 33
User.all
activerecord (4.1.4) lib/active_record/scoping/named.rb, line 28
User.where
activerecord (4.1.4) lib/active_record/querying.rb, line 10
OrmAdapter::ActiveRecord#get
orm_adapter (0.5.0) lib/orm_adapter/adapters/active_record.rb, line 17
User.serialize_from_session
devise (3.2.4) lib/devise/models/authenticatable.rb, line 208
block (2 levels) in Warden::SessionSerializer#user_deserialize
devise (3.2.4) lib/devise.rb, line 462
Warden::SessionSerializer#fetch
warden (1.2.3) lib/warden/session_serializer.rb, line 34
Warden::Proxy#user
warden (1.2.3) lib/warden/proxy.rb, line 212
Warden::Proxy#_perform_authentication
warden (1.2.3) lib/warden/proxy.rb, line 318
Warden::Proxy#authenticate!
warden (1.2.3) lib/warden/proxy.rb, line 127
RegistrationsController#authenticate_user!
devise (3.2.4) lib/devise/controllers/helpers.rb, line 50
RegistrationsController#authenticate_scope!
devise (3.2.4) app/controllers/devise/registrations_controller.rb, line 124
block in ActiveSupport::Callbacks::Callback#make_lambda
activesupport (4.1.4) lib/active_support/callbacks.rb, line 424
block in ActiveSupport::Callbacks::Filters::Before.halting_and_conditional
activesupport (4.1.4) lib/active_support/callbacks.rb, line 143
RegistrationsController#run_callbacks
activesupport (4.1.4) lib/active_support/callbacks.rb, line 86
RegistrationsController#process_action
actionpack (4.1.4) lib/abstract_controller/callbacks.rb, line 19
RegistrationsController#process_action
actionpack (4.1.4) lib/action_controller/metal/rescue.rb, line 29
block in RegistrationsController#process_action
actionpack (4.1.4) lib/action_controller/metal/instrumentation.rb, line 31
This is an old post, but the only one that asks about this exact issue, and there's no real solution. I was getting an error when attempting to use devise and acts_as_tenant without subdomains. I wanted to look up the tenant based on the user. This is the error I was getting: ActsAsTenant::Errors::NoTenantSet.
There are solutions here, but these didn't work for me.
The solution I found was to override some methods that Devise uses to extend the User model, so that these methods use unscoped as shown here. Using devise 4.6.2, acts_as_tenant 0.4.3, Rails 5.2.3
app/models/devise_overrides.rb
module DeviseOverrides
def find_for_authentication(conditions)
unscoped { super(conditions) }
end
def serialize_from_session(key, salt)
unscoped { super(key, salt) }
end
def send_reset_password_instructions(attributes={})
unscoped { super(attributes) }
end
def reset_password_by_token(attributes={})
unscoped { super(attributes) }
end
def find_recoverable_or_initialize_with_errors(required_attributes, attributes, error=:invalid)
unscoped { super(required_attributes, attributes, error) }
end
def send_confirmation_instructions(attributes={})
unscoped { super(attributes) }
end
def confirm_by_token(confirmation_token)
unscoped { super(confirmation_token) }
end
end
Then in app/models/user.rb:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :invitable, :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :validatable
belongs_to :account
accepts_nested_attributes_for :account
acts_as_tenant(:account)
extend DeviseOverrides
end
Now you can add a config/intializers/acts_as_tenant.rb and everything will continue to work.
ActsAsTenant.configure do |config|
config.require_tenant = true
end
My app/controllers/application_controller.rb looks like this:
class ApplicationController < ActionController::Base
set_current_tenant_through_filter
before_action :set_tenant
before_action :authenticate_user!
private
def set_tenant
current_account = current_user.account
set_current_tenant(current_account)
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With