I want to interrupt the default registration action in my rails application, changing email validation. All I need is to have email field unique ONLY if that user is already registered AND has role 'X'
.
I've tried the following but my application returns "Email has already been taken"
message:
validation:
validates_uniqueness_of :email, {allow_blank: true, if: :already_exists_as_x?}
def already_exists_as_x?
User.where(email: self.email, role: :X).exists?
end
(I will be glad for any help)
Assuming your model includes :validatable module of Devise, you can remove this module from your model and write your own validations as you desire.
In your model (say user.rb) your devise call contains :validatable like:
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :confirmable, :trackable
Remove or comment :validatable from this call, then your own validations should work as you expected.
If you are using Rails 5, you need to override the below method in your User model
def will_save_change_to_email?
if User.where(email: self.email, role: :X).exists?
return true
else
return false
end
end
when you return true
, devise will go ahead and apply the uniqueness
check and when you return false
devise will not check for uniqueness
You will also need to remove the unique index
as by passing devise validation alone will not let you save the user
def change
remove_index :users, :name => :index_users_on_email
end
Note: once you remove the index and create records with duplicate email ids, you will not be able to add the unique index back again at a later moment as creating unique index will fail
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.