Edward F. <epfrederick@…> writes:
Is this simply to illustrate callbacks? Would it not be easier to
create a virtual accessor:
I’m just wondering if I’m missing something about the whole
form->action->AR->save cycle where this alternate technique would be
worse than the callback method.
I can answer my own question here in that it would be hard to enforce
password policies without a transient plain-text version to validate
against; however, the question remains: what is the best practice?
I tried several ways of accomplishing the same goal; after some
I settled on the “virtual” approach you describe as being the most
understand (and so theoretically the most maintainable). Other than
I don’t see that one method has any benefit over the other.
As you suggest in your comment about enforcing password policies, you
add a little bit more code to make the virtual attribute approach work
validation. Here’s what I did (inside my model):
@password = password
salt = random_string(10)
hash = Digest::SHA1.hexdigest(salt + password)
self.password_salt = salt
self.password_hash = hash
return @password if @password
return ‘password’ if not self.password_hash.blank?
return Digest::SHA1.hexdigest(self.password_salt + password) ==
Basically, my password= is the same as yours, with the addition of doing
salt stuff and setting an instance variable to the plain-text password.
instance variable is never saved, so it is indeed “transient”, as you
but it’s available for the password method to access for purposes of
Since we don’t save the plain-text password we have to come up with
to return when the password method is called and the @password instance
is no longer available–so I return the string “password”: it will pass
validations, so it serves nicely. You could return the password hash,
longer than the length limit I have on the password field in my
up this way I can put all my password rules in the model as field
and everything automagically works just the way you would want it to.
The third method is what I use to actually check whether the password a
types is correct or not; I decided to encapsulate it in the model so
none of the
rest of my code needs to know anything about salts or any other