通常在我们创建模型时,比如说User
,它的属性与数据库字段匹配。
例如,如果我的相应数据库表users_development
包含字段name
和score
,那么当我创建User
类的实例时,我只需键入user = User.create(:name => "MyName", :score => 85)
。
现在,Devise创建了一个包含字段email
和encrypted_password
的迁移文件,但我看不到字段password
(从安全的角度来看,这是非常合乎逻辑的)。
在查看论坛帖子时,我看到了许多例子,例如User.create(:email =>"me@domain.com", :password => "foo")
。那么,password
来自哪里?它不是表users_development
的字段。现场背后发生了什么?我查看了http://rubydoc.info/github/plataformatec/devise/master/Devise上的文档,但找不到任何解释。
答案 0 :(得分:3)
User.create(:email => "me@domain.com", :password => "foo")
不会直接创建包含这些确切字段的数据库记录。相反,它在参数哈希中为每对使用public_send("#{k}=", v)
。所以真的,它在内部做了类似的事情:
user = User.new
user.email = "me@domain.com"
user.password = "foo"
user.save
即使您没有password
数据库字段,也会更新encrypted_password
字段的设计DatabaseAuthenticatable
module adds a password=
method:
def password=(new_password)
@password = new_password
self.encrypted_password = password_digest(@password) if @password.present?
end
答案 1 :(得分:2)
This method可以解决问题:
# Generates password encryption based on the given value.
def password=(new_password)
@password = new_password
self.encrypted_password = password_digest(@password) if @password.present?
end
当调用create,update属性,build等时,rails将尝试为方法field=
调用每个字段,因此当您将:password => 'foo'
传递给create
时,它会执行类似的操作:
user = User.new
user.password = 'foo'
user.save
此方法允许使用未散列的密码构建模型,但是将散列的密码存储在数据库中。