Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use has_secure_password with field_with_errors

I am using has_secure_password to verify my user password and its confirmation. The problem I have is that when there are any errors, the fields are not being wrapped with a field_with_errors div. I know that I can add

validates_presence_of :password, :on => :create
validates_presence_of :password_confirmation, :on => :create

but that creates the following error message:

Password digest can't be blank.
Password can't be blank.
Password confirmation can't be blank

I would like to either make the has_secure_password wrap the fields with errors with a field_with_errors div or remove the "Password digest can't be blank." error altogether.

Thanks.

like image 370
T. Weston Kendall Avatar asked Dec 04 '22 16:12

T. Weston Kendall


2 Answers

The SecurePassword module which has this functionality is quite simple and worth a look. Good news is that in the master branch (Rails 4) it does validates_presence_of :password, :on => :create which will solve your problem, but in the meantime you might want to mimic the has_secure_password method on the User model yourself.

class User < ActiveRecord::Base
  attr_reader :password
  attr_accessible :password # ...
  validates_confirmation_of :password
  validates_presence_of :password, on: :create
  include ActiveModel::SecurePassword::InstanceMethodsOnActivation
end

Also make sure bcrypt is loaded in Gemfile.

gem 'bcrypt-ruby', '~> 3.0.0', require: 'bcrypt'

Hope that helps.

like image 166
ryanb Avatar answered Jan 09 '23 16:01

ryanb


As @ryanb stated, the validates_presence_of :password is fixed in master, but won't be backported. That fix also clears up the Password digest can't be blank. message.

So, in the model, you still need to add:

validates :password, presence: true, on: :create

As @henrique-zambon stated, there's no need to add a validates_presence_of :password_confirmation. To highlight the password confirmation field, without displaying that additional message, add an error on that field after you've displayed the errors.

Then, to hide the extra Password digest can't be blank. message, you can just remove it in the top of your form.

= form_for @user do |f|
  - if @user.errors.any?
    - @user.errors.delete(:password_digest)
    #error_explanation
      %h2= "#{pluralize(@user.errors.count, "error")} prohibited this user from being saved:"
      %ul
        - @user.errors.full_messages.each do |msg|
          %li= msg
    - @user.errors.add(:password_confirmation) if @user.errors.include?(:password)
like image 26
iosctr Avatar answered Jan 09 '23 14:01

iosctr