【问题标题】:email uniqueness validation with subdomain scope in devise设计中具有子域范围的电子邮件唯一性验证
【发布时间】:2017-05-10 09:09:43
【问题描述】:

我正在使用devise gem 进行注册 un My rails 5 API 现在我的问题是,如果子域不同,我想注册相同的电子邮件地址用户,所以我的步骤是

1) 更新用户索引

add_index :users, [:email, :subdomain], unique: true

2) 在 user.rb 中

devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable, :confirmable
validates :email, uniqueness: {:scope => :subdomain}

现在在控制台中

  • User.last

#<User id: 111, email: "test@gmail.com", subdomain: "test">

  • 使用相同的电子邮件和不同的子域创建新用户

User.create!(email: "test@gmail.com", subdomain: "test1")

错误

(0.2ms)  BEGIN
  User Exists (0.5ms)  SELECT  1 AS one FROM "users" WHERE 
 "users"."email" = $1 AND "users"."deleted_at" IS NULL AND 
 "users"."subdomain" = $2 LIMIT $3  [["email", 
 "test@gmail.com"], ["subdomain", "test1"], ["LIMIT", 1]]

  User Exists (0.3ms)  SELECT  1 AS one FROM "users" WHERE 
 "users"."email" = $1 AND "users"."deleted_at" IS NULL LIMIT $2  
 [["email", "test@gmail.com"], ["LIMIT", 1]]
 (0.1ms)  ROLLBACK
 ActiveRecord::RecordInvalid: Validation failed: Email has already been taken

我做错了什么?

【问题讨论】:

  • 我不确定 DB 中的索引是否聪明地检查范围的唯一性。一般来说,您不需要对 DB 层进行任何验证。所以尝试删除数据库层上的验证,它应该会有所帮助。
  • 你确定User.exist?(email: "test@gmail.com", subdomain: "test1")返回false
  • @AmitPatel 是的,它返回错误
  • 2.4.0 :012 > User.exists?(:email => "test@gmail.com", :subdomain => "test1") 用户存在 (0.7ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 AND "users"."subdomain" = $2 LIMIT $3 [["email", "test@gmail.com"], ["subdomain", "test1"], ["LIMIT", 1]] => 错误
  • @nautgrad - 你在说什么?使用数据库索引可以防止竞争条件,如果唯一性很重要,这是一个非常好的主意。 robots.thoughtbot.com/the-perils-of-uniqueness-validations

标签: ruby-on-rails api devise


【解决方案1】:

既然您有validatable,请将以下内容添加到您的用户模型中:

validates :email, presence: true
validates :subdomain, presence: true
validates :email, uniqueness: {:scope => :subdomain}

def email_required?
  false
end

def email_changed?
  false
end

参考:https://github.com/plataformatec/devise/wiki/How-To%3a-Allow-users-to-sign-in-with-something-other-than-their-email-address

【讨论】:

  • 但这会删除电子邮件的存在,我的意思是现在我可以创建没有电子邮件的用户。
  • 我想创建具有不同子域的相同电子邮件的用户,并且两者都是强制性的。
  • 像我现在一样自己添加验证
  • 您要添加validates_uniqueness_of :email, scope: 'subdomain' 和存在验证validates :email, :subdomain, presence: true
  • 还是同样的问题
猜你喜欢
  • 2021-08-22
  • 2014-06-08
  • 2018-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-23
相关资源
最近更新 更多