简体   繁体   中英

Rails: Devise and acts_as_tenant registration process

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM