I am using the acts_as_tenant gem to manage multi-tenancy, and I'm using devise to manage users.
I have only setup devise User model and Account model for tenants. I can create users against multiple tenants - this is all working fine EXCEPT when I attempt to create two users with the same email against different tenant ID's I get a uniqeness error. I am using the validates_uniqueness_to_tenant option as described.
User model
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation, :remember_me
acts_as_tenant(:account)
validates_uniqueness_to_tenant :email
end
Account model
class Account < ActiveRecord::Base
attr_accessible :name
end
Application Controller
class ApplicationController < ActionController::Base
set_current_tenant_by_subdomain(:account, :subdomain)
protect_from_forgery
end
This looks like it should be working based on all documentation in acts_as_tenant, do I need to override something at the devise level instead?
EDIT: After some head-scratching and a bit of a break, the problem is I believe because by default Devise has added a unique index to the Email column. This obviously does not gel with what acts_as_tenant wants to do... I will try removing the index and see whether Devise pukes or not.
EDIT 2: OK, have officially given up on this for now. I have hand-rolled authentication for the main site and this is working properly with acts_as_tenant. I can only assume some incompatibility between acts_as_tenant and Devise at some layer - beyond me to find it at this stage.
The only way to do this is by removing the validatable module from devise and run your own validations like so:
class User < ActiveRecord::Base
acts_as_tenant :account
attr_accessible :email, :password, :remember_me
#remove :validatable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable
#run own validations
#I've omitted any emailformatting checks for clarity's sake.
validates :email,
presence: true,
uniqueness: { scope: :account_id, case_sensitive: false }
validates :password,
presence: true,
length: { :in => 6..20 },
:if => :password_required?
protected
# copied from validatable module
def password_required?
!persisted? || !password.nil? || !password_confirmation.nil?
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