I'm debugging this problem with devise-- despite my best efforts I am still getting an error "password can't be blank" when updating a user without providing a password. I have tried the official solution, as well as the solution suggested in this SO question, but I am still getting the error despite ensuring the opts passed to update_attributes does not contain password
or password_confirmation
.
I am trying to figure out how to debug this-- I am poking around in devise, activerecord, activemodel, etc, but I can't seem to stick a debug statement in exactly the right spot.
When I run User.validators
, I get the following output:
=> [#<ActiveRecord::Validations::PresenceValidator:0x007ff513507890 @attributes=[:email], @options={:if=>:email_required?}>,
#<ActiveRecord::Validations::UniquenessValidator:0x007ff51350fef0
@attributes=[:email],
@klass=
User(id: integer, name: string, email: string, encrypted_password: string, reset_password_token: string, reset_password_sent_at: datetime, remember_created_at: datetime, sign_in_count: integer, current_sign_in_at: datetime, last_sign_in_at: datetime, current_sign_in_ip: string, last_sign_in_ip: string, created_at: datetime, updated_at: datetime, school_id: integer, invitation_token: string, invitation_created_at: datetime, invitation_sent_at: datetime, invitation_accepted_at: datetime, invitation_limit: integer, invited_by_id: integer, invited_by_type: string, type: string, opt_in: boolean),
@options={:case_sensitive=>true, :allow_blank=>true, :if=>:email_changed?}>,
#<ActiveModel::Validations::FormatValidator:0x007ff51351c560
@attributes=[:email],
@options={:with=>/\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/, :allow_blank=>true, :if=>:email_changed?}>,
#<ActiveRecord::Validations::PresenceValidator:0x007ff5148e4b60 @attributes=[:password], @options={:if=>:password_required?}>,
#<ActiveModel::Validations::ConfirmationValidator:0x007ff50efb85a0 @attributes=[:password], @options={:if=>:password_required?}>,
#<ActiveModel::Validations::LengthValidator:0x007ff5150e91d0
@attributes=[:password],
@options={:allow_blank=>true, :minimum=>8, :maximum=>128}>,
#<ActiveRecord::Validations::PresenceValidator:0x007ff515125a90 @attributes=[:name], @options={}>]
Devise itself is (in theory) smart enough to not ask for a password if you haven't changed it:
devise/lib/devise/models/validatable.rb
validates_presence_of :password, if: :password_required?
validates_confirmation_of :password, if: :password_required?
# ...
def password_required?
!persisted? || !password.nil? || !password_confirmation.nil?
end
And you can see this is reflected in the User.validators
check above.
However, I am still getting this error!
How can I track down where this error is being added to the object, and who inserted the offending validator?