I have a database table that contains encrypted passwords along with other information relating to users. When I do an update_attributes operation on a row in the table with a hash that does not contain a password, the password gets reset to the empty string. How can I stop this?
Remove the password key/value pair from the params hash before the update-attributes call if the password value is blank.
The hash does not contain a password key/value pair. In spite of this, the password is set to the empty string.
Parameters: {“utf8”=>“✓”, “authenticity_token”=>“AdPOoGvw9LXnkLEen9NzXo/yhwESO6hRxnICD2eK4Rk=”, “user”=>{“role_id”=>“3”}, “commit”=>“Update User”, “id”=>“1”}
> > I have a database table that contains encrypted passwords along with > other information relating to users. When I do an update_attributes > operation on a row in the table with a hash that does not contain a > password, the password gets reset to the empty string. How can I stop this?
Remove the password key/value pair from the params hash before the update-attributes call if the password value is blank.
The hash does not contain a password key/value pair. In spite of this, the password is set to the empty string.
Parameters: {"utf8"=>"✓", "authenticity_token"=>"AdPOoGvw9LXnkLEen9NzXo/yhwESO6hRxnICD2eK4Rk=", "user"=>{"role_id"=>"3"}, "commit"=>"Update User", "id"=>"1"}
Have you got any callbacks in the model (before_save for example)? What does the log (log/development.log) show for the action? It should show the sql.
If you still can't see it post the action code, the model (strip out any irrelevant methods) and the log (just for the action).
Colin
Colin
What filters run in the model? What observers are operating? It would be worth setting a breakpoint at your update_attribute line and following through from there to see what happens to your password attribute.
I understand the problem now, but I do not see the solution. The model has a before_save filter that is causing the password to be reset. How do I stop this on an update?
require ‘authenticators/sql_encrypted’
class User < ActiveRecord::Base
belongs_to :role belongs_to :person
include CASServer::Authenticators::SQLEncrypted::EncryptedPassword
attr_accessor :password
validates :password, :confirmation => true, :length => { :within => 7…20 }, :format => { :with => /^.(?=.{7,20})(?=.[a-zA-Z])(?=.[0-9])(?=.[`~!@#$%^&-_=+|;':",./<>?]).$/ }, :presence => true, :if => :password_required?
validates_uniqueness_of :username
before_save :encrypt_password
protected
def password_required? encrypted_password.blank? || password.present? end
def encrypt_password self.encrypted_password = encrypt(self.password) end
end
The same way I said before - only run it if the password has been populated:
def encrypt_password self.encrypted_password = encrypt(self.password) unless self.password.blank? end
But you will probably need to add same validation to ensure there is an encrypted_password - otherwise it would be possible to create accounts with blank passwords...
Thank you.
Also note that before_save (and pretty much all the callbacks) take :if and :unless parameters, like so
before_save do_something, :if => Proc.new {|model| model.some_boolean_attr_or_method }