我正在使用acts_as_tenant gem来管理多租户,而我正在使用设计来管理用户。
我只为租户设置了用户模型和帐户模型。 我可以针对多个租户创建用户 - 这一切都正常工作除了当我尝试使用相同的电子邮件创建两个用户对不同的租户ID时,我得到了一个单一的错误。 我正在使用所描述的validates_uniqueness_to_tenant选项。
用户模型
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
帐户模型
class Account < ActiveRecord::Base
attr_accessible :name
end
应用程序控制器
class ApplicationController < ActionController::Base
set_current_tenant_by_subdomain(:account, :subdomain)
protect_from_forgery
end
看起来它应该基于acts_as_tenant中的所有文档工作,我是否需要在设计级别覆盖某些内容?
编辑:经过一番头疼和一点休息后,问题是我相信,因为默认情况下,Devise为电子邮件专栏添加了一个唯一索引。 这显然不会影响act_as_tenant想要做的事情...... 我会尝试删除索引,看看是否设计了Devise。
编辑2:好的,现在已经正式放弃了。我对主站点进行了手动滚动身份验证,这与acts_as_tenant一起正常运行。 我只能假设acts_as_tenant和Devise在某一层之间存在一些不兼容性 - 除了我在这个阶段找到它。
答案 0 :(得分:8)
执行此操作的唯一方法是从设计中删除可验证模块并运行您自己的验证,如下所示:
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
答案 1 :(得分:0)
我还没有对它进行过测试,但我想知道更改顺序是否有助于act_as_tenant在设计接管之前完成它的工作。
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
答案 2 :(得分:0)
刚刚遇到这个问题。 Sweam的解决方案非常好。
但我更喜欢不覆盖默认行为。所以我提出了这个解决方案:
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
我们删除了电子邮件的默认验证错误,因此忽略了验证检查,我们再次进行自己的验证。
我添加的是来自Validatable模块,但我已经添加了:scope
。
保持秩序很重要。在devise
命令后添加上面的代码。
答案 3 :(得分:0)
我将其解析为:
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