15

How can I customize error messages to override devise passwords controller?

class PasswordsController < Devise::PasswordsController
  def create
    self.resource = resource_class.send_reset_password_instructions(params[resource_name])

    if resource.errors.empty?
      set_flash_message(:notice, :send_instructions) if is_navigational_format?
      respond_with resource, :location => home_path
    else
      binding.pry
      flash[:devise_password_error] =  (resource.errors.map do |key, value|
        value.capitalize
      end).flatten.join('|')
      redirect_to home_path and return
    end
  end
  def edit
    self.resource = resource_class.new
    resource.reset_password_token = params[:reset_password_token]
  end
end

resource.errors is available in this method but it contains default messages such as Email not found and Email can't be blank. i need to customize this messages. I've tried to remove :validatable from my user model and add custom validators but this works only for my custom registrations controller derived from Devise::RegistrationsController and not for custom passwords controller.

Is there any solution?

Promise Preston
  • 24,334
  • 12
  • 145
  • 143
roman
  • 5,100
  • 14
  • 44
  • 77
  • I know this is old, but check [this answer](http://stackoverflow.com/a/18578028/1964165) for a more generic and clean approach. – akhanubis Sep 02 '13 at 17:22

4 Answers4

18

The answer is to modify config/locales/devise.en.yml but you must add the settings, they are not there by default.

en:
  activerecord:
    errors:
      models:
        user:
          attributes:
            password:
              confirmation: "does not match"
              too_short: "is too short (minimum is %{count} characters)"

Credit for this goes to Vimsha who answered virtually the same question for me.

Community
  • 1
  • 1
Justin
  • 26,443
  • 16
  • 111
  • 128
  • 1
    You should use %{count} in the error message rather than hard coding the minimum value. count is passed to I18n.t by the range validator, and therefore will always match the devise setting. – ReggieB Feb 16 '15 at 09:08
9

Devise messages are located in config/locales/devise.en.yml

I'm not sure which message you're trying to override, but that's where you want to do that.

Jesse Wolgamott
  • 40,197
  • 4
  • 83
  • 109
  • 4
    The messages i want to override are not located there. These message i want to change are default messages used when validation fails and `config/locales/devise.en.yml` contains devise information messages. – roman Feb 17 '12 at 16:11
  • Those messages are indeed not in there, but you can add them and it will work. See my answer above. – Justin Dec 11 '13 at 23:28
0

It's not ideal, but based on this related ticket I've got it working with the following (which I know is a bit of a hack, but it works):

module DeviseHelper
  def devise_error_messages!
     resource.errors.full_messages.map { |msg| msg == 'Email not found' ? 'The email address you entered could not be found. Please try again with other information.' : msg }.join('<br/>')
  end
end

Put this in a module called devise_helper.rb in your /app/helpers directory

Community
  • 1
  • 1
johnd
  • 516
  • 5
  • 9
0

Add this to your routes.rb

devise_for :users, controllers: { passwords: 'passwords' }

or

devise_for :users, :controllers => { :passwords => 'passwords' }