User uniqueness with development and act_as_tenant in rails 3

I use acts_as_tenant gem to manage multi-tenancy, and I use a utility to manage users.

I only have to configure the user model and account model for tenants. I can create users against several tenants - all this works fine EXCEPTION, when I try to create two users with the same email address against different tenant identifiers, I get an uniqeness error. I use the validates_uniqueness_to_tenant parameter 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 

It seems like it should work on the basis of all the documentation in act_as_tenant, is it necessary to redefine something at the development level instead?

EDIT: After some head scratches and a little break, the problem is what I think, because by default Devise added a unique index to the Email column. This is clearly not a gel with what act_as_tenant wants to do ... I will try to remove the index and see if Devise gets confused or not.

EDIT 2: OK, officially abandoned this at the moment. I have manual authentication for the main site and this works correctly with act_as_tenant. I can only assume some incompatibility between act_as_tenant and Devise at some level - outside of me, to find it at this stage.

+7
source share
4 answers

The only way to do this is to remove the validatable module from development and perform your own validation as follows:

 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 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 
+8
source

I have not tested it, but I am wondering if changing the order can help act_as_tenant do its job before the device accepts.

 class User < ActiveRecord::Base acts_as_tenant(:account) validates_uniqueness_to_tenant :email # 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 end 
0
source

Just stumbled upon this question. Sweam's solution is pretty good.

But I prefer not to override the default behavior. So I came up with this solution:

 validate :remove_old_email_validation_error validates_uniqueness_of :email, :allow_blank => true, :if => :email_changed?, :scope => [:account_id] private def remove_old_email_validation_error errors.delete(:email) end 

We remove the default validation error for email, so we ignore the validation verification, and again we do our own verification. What I added is the Validatable module, but I added :scope to it.

It is important to keep order. Add the code above after the devise .

0
source

I solved it as:

validate :remove_old_uniquess_email_error

 private def remove_old_uniquess_email_error errors.delete(:email) if self.company_id.nil? && errors[:email].present? && errors[:email] == ["already taken"] end 
0
source

Source: https://habr.com/ru/post/920787/


All Articles