I am working on making my Rails 4.2.0 / Ruby 2.2.1 application ready to be used with Rails 5 / Ruby 2.2.3. This app uses Devise gem. Problem For an existing user in my database, when I try to update its password using Devise’s update_with_password method (defined in Devise::Models::DatabaseAuthenticatable) password’s presence validation errors are not generated when params argument to this method contains following value:
params = { current_password: ‘password’, password: ‘’, password_confirmation: ‘changed_password’ }
``
This is the case when using Rails 5 alpha version and Devise’s Rails 5 branch (branch and revision details are given at the bottom). When using Rails 4.2.0 and Devise 3.5.2 password presence as well as confirmation not matched errors gets generated. Such behavior when using Rails 5 alpha version and Devise’s Rails 5 branch code-base is breaking few of my passing specs. Please see the output from Rails console below in both the environments: Ruby 2.2.1 / Rails 4.2.0 / Devise 3.5.2
Loading test environment (Rails 4.2.0)
2.2.1 :001 > u = User.first
User Load (0.7ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
=> #<User id: 28, email: "xyz@example.com", encrypted_password: "$2a$04$2VDTFE1GhbOQalt8/BmhLujNH40jipYFW4POaqGfOA2...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, confirmation_token: "NvTuUzjnC_DSZsEfaCrE", confirmed_at: nil, confirmation_sent_at: "2015-11-25 11:30:14", unconfirmed_email: nil, failed_attempts: 0, unlock_token: nil, locked_at: nil, created_at: "2015-11-25 11:30:14", updated_at: "2015-11-25 11:30:14", provider_id: 65, authentication_token: "Aa59bHvAYguhvcX_3VPS">
2.2.1 :002 > params = { current_password: 'password', password: '', password_confirmation: 'changed_password' }
=> {:current_password=>"password", :password=>"", :password_confirmation=>"changed_password"}
2.2.1 :003 > u.update_with_password(params)
(0.2ms) BEGIN
Provider Load (0.3ms) SELECT "providers".* FROM "providers" WHERE "providers"."id" = $1 LIMIT 1 [["id", 65]]
(0.2ms) ROLLBACK
=> false
2.2.1 :004 > u.errors
=> #<ActiveModel::Errors:0x0000000769f238 @base=#<User id: 28, email: "xyz@example.com", encrypted_password: "$2a$04$2VDTFE1GhbOQalt8/BmhLujNH40jipYFW4POaqGfOA2...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, confirmation_token: "NvTuUzjnC_DSZsEfaCrE", confirmed_at: nil, confirmation_sent_at: "2015-11-25 11:30:14", unconfirmed_email: nil, failed_attempts: 0, unlock_token: nil, locked_at: nil, created_at: "2015-11-25 11:30:14", updated_at: "2015-11-25 11:30:14", provider_id: 65, authentication_token: "Aa59bHvAYguhvcX_3VPS">, @messages={:password=>["can't be blank"], :password_confirmation=>["doesn't match Password"]}>
2.2.1 :005 > u.errors.full_messages
=> ["Password can't be blank", "Password confirmation doesn't match Password"]
``
Ruby 2.2.3 / Rails 5.0.0.alpha / Devise Rails 5 branch (github: ‘twalpole/devise’, branch: ‘rails5’)
Loading test environment (Rails 5.0.0.alpha)
2.2.3 :001 > u = User.first
User Load (0.8ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
=> #<User id: 28, email: "xyz@example.com", encrypted_password: "$2a$04$2VDTFE1GhbOQalt8/BmhLujNH40jipYFW4POaqGfOA2...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, confirmation_token: "NvTuUzjnC_DSZsEfaCrE", confirmed_at: nil, confirmation_sent_at: "2015-11-25 11:30:14", unconfirmed_email: nil, failed_attempts: 0, unlock_token: nil, locked_at: nil, created_at: "2015-11-25 11:30:14", updated_at: "2015-11-25 11:30:14", provider_id: 65, authentication_token: "Aa59bHvAYguhvcX_3VPS">
2.2.3 :002 > params = { current_password: 'password', password: '', password_confirmation: 'changed_password' }
=> {:current_password=>"password", :password=>"", :password_confirmation=>"changed_password"}
2.2.3 :003 > u.update_with_password(params)
>>>> update_with_password (original params): {:current_password=>"password", :password=>"", :password_confirmation=>"changed_password"}
>>>> update_with_password (updated params): {:password_confirmation=>"changed_password"}
(0.2ms) BEGIN
Provider Load (0.3ms) SELECT "providers".* FROM "providers" WHERE "providers"."id" = $1 LIMIT 1 [["id", 65]]
(0.1ms) ROLLBACK
=> false
2.2.3 :004 > u.errors
=> #<ActiveModel::Errors:0x00000006b57f60 @base=#<User id: 28, email: "xyz@example.com", encrypted_password: "$2a$04$2VDTFE1GhbOQalt8/BmhLujNH40jipYFW4POaqGfOA2...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, confirmation_token: "NvTuUzjnC_DSZsEfaCrE", confirmed_at: nil, confirmation_sent_at: "2015-11-25 11:30:14", unconfirmed_email: nil, failed_attempts: 0, unlock_token: nil, locked_at: nil, created_at: "2015-11-25 11:30:14", updated_at: "2015-11-25 11:30:14", provider_id: 65, authentication_token: "Aa59bHvAYguhvcX_3VPS">, @messages={:password_confirmation=>["doesn't match Password"]}, @details={:password_confirmation=>[{:error=>:confirmation, :attribute=>"Password"}]}>
2.2.3 :005 > u.errors.full_messages
=> ["Password confirmation doesn't match Password"]
``
Gemfile.lock contents of which branch, if any and revisions of Rails and Devise gems my application is using.
GIT
remote: git://github.com/twalpole/devise.git
revision: cce8cf676e39e1bc78b177e0ca2b263747a82974
branch: rails5
specs:
devise (3.5.2)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 3.2.6, < 5)
responders
thread_safe (~> 0.1)
warden (~> 1.2.3)
GIT
remote: https://github.com/rack/rack.git
revision: c393176b0edf3e5d06cabbb6eb9d9c7a07b2afa7
specs:
rack (2.0.0.alpha)
json
GIT
remote: https://github.com/rails/arel.git
revision: 3c429c5d86e9e2201c2a35d934ca6a8911c18e69
specs:
arel (7.0.0.alpha)
GIT
remote: https://github.com/rails/rails.git
revision: 58df2f4b4abcce0b698c2540da215a565c24cbc9
specs:
actionmailer (5.0.0.alpha)
actionpack (= 5.0.0.alpha)
actionview (= 5.0.0.alpha)
activejob (= 5.0.0.alpha)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 1.0, >= 1.0.5)
actionpack (5.0.0.alpha)
actionview (= 5.0.0.alpha)
activesupport (= 5.0.0.alpha)
rack (~> 2.x)
rack-test (~> 0.6.3)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.0.0.alpha)
activesupport (= 5.0.0.alpha)
builder (~> 3.1)
erubis (~> 2.7.0)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
activejob (5.0.0.alpha)
activesupport (= 5.0.0.alpha)
globalid (>= 0.3.0)
activemodel (5.0.0.alpha)
activesupport (= 5.0.0.alpha)
builder (~> 3.1)
activerecord (5.0.0.alpha)
activemodel (= 5.0.0.alpha)
activesupport (= 5.0.0.alpha)
arel (= 7.0.0.alpha)
activesupport (5.0.0.alpha)
concurrent-ruby (~> 1.0)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
method_source
minitest (~> 5.1)
tzinfo (~> 1.1)
rails (5.0.0.alpha)
actionmailer (= 5.0.0.alpha)
actionpack (= 5.0.0.alpha)
actionview (= 5.0.0.alpha)
activejob (= 5.0.0.alpha)
activemodel (= 5.0.0.alpha)
activerecord (= 5.0.0.alpha)
activesupport (= 5.0.0.alpha)
bundler (>= 1.3.0, < 2.0)
railties (= 5.0.0.alpha)
sprockets-rails (>= 2.0.0)
railties (5.0.0.alpha)
actionpack (= 5.0.0.alpha)
activesupport (= 5.0.0.alpha)
method_source
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
``
Can anybody please shed light on what is causing this weird behaviour? Is this caused due to changes in Rails 5 ActiveModel validations implementation or some change in Devise’s code for making it Rails 5 compatible?
Thanks.