-
Notifications
You must be signed in to change notification settings - Fork 5.5k
How To: Scope email validation
This feature is not merged.
By default, Devise's validatable module validates the uniqueness of the email attribute in the User model.
But, sometimes, it's useful to scope the email uniqueness validation into some context. Using subdomains or some soft-deletion approach are good examples of these cases.
Devise now comes with an option to define an array of scopes for email validation.
Let's suppose your User
model belongs to an Account
and you want to allow the same email into multiple Accounts. You just need to add the email_scope
option to your devise.rb
file like this:
Devise.setup do |config|
# Option to scope the email uniqueness validator. Default is nil;
config.email_scope = [:account_id]
end
By doing this, the validatable module will scope the :email
uniqueness validation to the defined keys.
Unfortunately, using this option has some caveats and additional work is needed to make the scope work as desired and without affecting some other functionalities of Devise.
Devise adds a database unique index to the email
attribute. Even if you add the email_scope
option, this index will continue to exist, so you need to manually remove it. It's also important to add another unique index scoped to our needs.
class ChangesUniqueIndexOfUsers < ActiveRecord::Migration
def up
remove_index :users, :email
add_index :users, [:email, :account_id], unique: true
end
def down
add_index :users, :email, unique: true
remove_index :users, [:email, :account_id]
end
end
By adding a scope to the email
key, you may end up with multiple users with the same email address. This will cause the “recoverable” module not to work well, as it will only include a link in the password reset e-mail to the first account for which it finds a matching e-mail. Here is a thread on the Google Group about how to implement adding all the user information into the password reset email.