I now think it may be the peculiarity of the model: it validates
presence of password confirmation, which makes no sense when password
itself isn't or shouldn't be updated.
That is indeed weird - the only validation I've ever used in conjunction with the confirmation field is validates_confirmation_of. You can check user.errors to see all the errors rails thinks the object has.
Thanks, it was indeed missing password + confirmation causing the
ROLLBACK.
irb(main):004:0> user.errors
=> #<ActiveModel::Errors:0x29fe1b30 @base=#<User id: 1, name: "Example
User", email: "exampl@railstutorial.org", created_at: "2013-05-12
12:47:23", updated_at: "2013-05-19 07:55:25", password_digest: "$2a
$10$0i9ihaDD9nU6QxiGNiKEGeIarY9faPWY9lAAlLIzYz8U...">,
@messages={:password_confirmation=>["can't be blank"], :password=>["is
too short (minimum is 6 characters)"]}>
has_secure_password must be something new in Rails 4. It does
everything validates_confirmation_of does.
And attr_accessible also seems to have become a thing from the past.
Validation should be conditional. Considering that both password and
password_confirmation are virtual and are never saved to the database
(only password_digest, a special field expected by
has_secure_password), their validation should be special cased (like
only password being present to signify desire to change it, thus
trigger the confirmation check).