在Devise中跳过电子邮件validation

在Devise中,Validatable模块包含validates_uniqueness_of :email, :allow_blank => true, :if => :email_changed? 如何禁用此validation器?

Per Devise自己的Validatable模块文档 ……

Validatable为用户电子邮件和密码创建所有必需的validation。 它是可选的,因为您可能想要自己创建validation。 自动validation电子邮件是否存在,唯一且其格式是否有效。 还测试密码,确认和长度的存在。

强调我的重点。

您应该禁用Validatable模块并滚动自己的validation。

 devise :database_authenticatable, :registerable, :rememberable, :trackable, :timeoutable, :confirmable, :recoverable, :lockable # :validatable <-- this one needs to go 

查看lib/devise/models/validatable.rb的内容,并将相关部分拉入您自己的User类。 对于当前的3.2.x版本行,它应该看起来像这样......

 class User < ActiveRecord::Base # From Devise module Validatable validates_presence_of :email, if: :email_required? validates_uniqueness_of :email, allow_blank: true, if: :email_changed? validates_format_of :email, with: email_regexp, allow_blank: true, if: :email_changed? validates_presence_of :password, if: :password_required? validates_confirmation_of :password, if: :password_required? validates_length_of :password, within: password_length, allow_blank: true # [ ... ] The rest of your model stuff protected # From Devise module Validatable def password_required? !persisted? || !password.nil? || !password_confirmation.nil? end # From Devise module Validatable def email_required? true end end 

然后进行必要的更改。

一个现实世界的场景:我在许多项目中使用Paranoia gem ,这不适用于这个模块。 所以我删除它并自定义电子邮件唯一性检查以读取为...

 validates_uniqueness_of :email, scope: :deleted_at 

我担心你会发现它非常丑陋但是:

在1.x设计中(我们正在讨论分支1.x,对吗?)没有选择它的选项,所以唯一的方法是在设计指令后删除类定义中不必要的validation器:

class User扩展了Mongoid文档(没有mater,AR在这里是相同的,只是在下面的delete_if方法中放置AR Validator类)并包含设计初始化器,所以这个hack似乎有效:

 User._validators[:email].try{ |validators| validators.delete_if{ |validator| validator.is_a? Mongoid::Validations::UniquenessValidator } } 

因此,User类定义可以是:

 class User include Mongoid::Document devise :database_authenticatable, :registerable, :validatable _validators[:email].try{ |validators| validators.delete_if{ |validator| validator.is_a? Mongoid::Validations::UniquenessValidator } } # ... end 

根据您的需要,您可能不需要完全撕掉Validatable模块。 如果您只想在电子邮件列中允许空字符串,那么您可以覆盖email_required? 方法…

 class User ... def email_required? false end