devise custom error message when email already exists and account is active
Asked Answered
P

1

0

I have a User model with devise and have a active column which indicates if the user is active or not. After the trial period is over the account will be inactive unless the user sign up for one of the plans.

I am currently showing custom error message to the users when email already exists using devise like below

en:
  activerecord:
    errors:
      models:
        user:
          attributes:
            email:
              taken: 'This email address has been used already. Please contact support if you would like more access'

However sometimes a user with active account in trial period tries to sign up again, in that case i want to display a different error message something like 'Please sign in __sign__in__link'

What would be proper way to display error message conditionally when email already exists and account is active?

Plataea answered 6/11, 2020 at 10:46 Comment(3)
How do you know if the person trying to register falls into the first or second category?Swartz
Either way, you would need to edit your registrations controller. You can choose which errors get added there, so you would just need to add your custom error message into your locales file above, and then reference that in your controller when your conditions are metSwartz
@Swartz thanks for your reply. I have a field in the user table which tells me if the user is active or not.Plataea
E
0

The way to handle this isn't really through a validation since validations don't have the context of where you are in the application flow.

And just displaying a little error on the form is a lot less helpful to the user then displaying a flash message.

Devise makes this fairly easy as Devise::RegistrationsController#create yields to let subclasses "tap into" the flow:


class MyRegistrationsController < Devise::RegistrationsController
  def create
    super do
      if has_duplicate_email? && user_is_active?
        flash.now("You seem to already have an account, do you want to #{ link_to(new_session_path, "log in") } instead?")
      end
    end 
  end

  private 

  def has_duplicate_email?
    return false unless resource.errors.has_key?(:email)
    resource.errors.details[:email].any? do |hash|
      hash[:error] == :taken
    end
  end

  def user_is_active?
    User.find_by(email: resource.email)&.active?
  end
end
# routes.rb
devise_for :users, controllers: {
  registrations: :my_registrations
}
Escalante answered 6/11, 2020 at 12:9 Comment(3)
many thanks for your reply. isn't there any way i can override the validation message instead of updating the flash message?Plataea
Thanks @max, I tried to do that, but i am not sure how do i add a new token for example i want to taken_active, so in place of taken error in resource.errors i want to add taken_active, also do i do this in registration_controller or some place else?Plataea
Instead of flash.now in the code above use resource.errors.delete(:email); resource.errors.add(:whatever_you_want, 'Whatever message'). Its not really that difficult. But its really not a good solution here. api.rubyonrails.org/classes/ActiveModel/Errors.htmlEscalante

© 2022 - 2024 — McMap. All rights reserved.