As Anne_Ominous wrote in the comments, this solution needs salts to be truly secure. One reply to Anne links to a sentence in the bcrypt-ruby docs: "bcrypt-ruby automatically handles the storage and generation of these salts for you.". However, there's something I don't understand. Where are the salts stored? The linked article mentions only that the model needs a password_digest field. If the salt is stored alongside it, shouldn't we need a password_salt field too? And if the salt is stored in a separate database, isn't that inefficient and unscaleable?