I am using acts_as_tenant gem to manage a multi-tenant platform while using devise to manage users. A User in our system acts_as_tenant and belongs_to Organization. Organization acts_as_tenant and has_many Users.
We are having trouble understanding what the best way to ensure that upon sign up a User gets created, an Organization gets created, a Tenant gets created (based on the Org), and the current tenant gets saved subsequently setting the correct tenant_id on the User and Org model.
The problem is in order for a User to be valid it must have an organization and a tenant. So before validation happens we must create the org and the tenant, we are trying to do so with below code:
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :confirmable
acts_as_tenant(:tenant)
acts_as_paranoid
belongs_to :organization
before_validation :create_organization
def create_organization
if self.organization_id.nil?
org = Organization.new(name: self.email)
org.uuid = UUIDTools::UUID.random_create.to_s
self.organization_id = org.uuid
end
end
end
class Organization < ApplicationRecord
acts_as_tenant(:tenant)
self.primary_key = :uuid
has_many :users
before_validation :create_tenant
def create_tenant
puts 'making new tenant'
t = Tenant.new(:short_name => self.name)
end
end
class ApplicationController < ActionController::Base
set_current_tenant_through_filter
before_action :find_current_tenant
def find_current_tenant
unless current_user.nil?
set_current_tenant(current_user.organization.tenant)
end
end
end
But the users org and tenant are not being created before validation causing validation errors 'tenant must exist', 'org must exist'.
Any help on best practices here?
I don't know your business logic but in order to do acts_as_tenant(:tenant)
your model has to have a relation defined to tenant
, which you don't seem to have. I think what you want to do (common use case) is:
class User < ActionController::Base
belongs_to :organization
acts_as_tenant(:organization)
end
class Organization < ActionController::Base
self.primary_key = :uuid
has_many :users
# and nothing else
end
You don't set the current tenant on the model. That is not correct. You do that on the Application Controller, by doing set_current_tenant(current_user.organization)
and nothing else
UPDATE: You mentionew a Tenant class now.
So now your organization class should define that relation
class Organization < ApplicationRecord
acts_as_tenant(:tenant)
self.primary_key = :uuid
has_many :users
belongs_to :tenant
before_validation :create_tenant
def create_tenant
puts 'making new tenant'
self.tenant ||= Tenant.create!(:short_name => self.name)
end
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.