Kva*_*ass 17 ruby instance-variables self ruby-on-rails-3
我正在关注Michael Hartl的RoR教程,它涵盖了密码加密的基础知识.这是目前的用户模型:
class User < ActiveRecord::Base
attr_accessor :password
attr_accessible :name, :email,: password, :password_confirmation
email_regex = /^[A-Za-z0-9._+-]+@[A-Za-z0-9._-]+\.[A-Za-z0-9._-]+[A-Za-z]$/
#tests for valid email addresses.
validates :name, :presence => true,
:length => {:maximum => 50}
validates :email, :presence => true,
:format => {:with => email_regex},
:uniqueness => {:case_sensitive => false}
validates :password, :presence => true,
:length => {:maximum => 20, :minimum => 6},
:confirmation => true
before_save :encrypt_password
private
def encrypt_password
self.encrypted_password = encrypt(password)
end
def encrypt(string)
string
end
end
Run Code Online (Sandbox Code Playgroud)
我发布了一个关于before_save不工作的上一个问题,事实证明我不小心做的是将我的encrypt_password写成:
def encrypt_password
@encrypted_password = encrypt(password)
end
Run Code Online (Sandbox Code Playgroud)
我知道如果self.encrypted_password设置encrypted_password属性,但为什么@encrypted_password也没有这样做呢?在上一篇关于before_save不工作的帖子的回复中,有人说实例变量在方法以我最初编码的方式结束后被"遗忘" - 为什么会这样?有人可以解释一下self和@ 在上面代码的上下文中的工作方式有何不同?
注意:我已经看过这里和这里的帖子,但是他们都说"self"正在调用attribute =方法,我甚至不知道这个方法在这里是如何存在的,因为我从来没有创建过它或者声明了encrypted_password w/attr_accessor.所以我仍然感到困惑,这不是重新发布这些问题.
Zab*_*bba 20
encrypted_passwordRails为您自动添加了访问者,因为users表中存在该名称的字段.
您添加到表格中的任何字段都将自动通过self.field_name.
这是Michael Hartl的教程encrypted_password在users表格中创建字段的地方.
另请查看user_spec.rb链接页面中的(清单7.3),作者正在测试该encrypted_password字段的存在.
更新:
正如@mu指出的那样,@它用于Ruby实例变量(又名"iv").但它encrypted_password是由Rails定义的"属性",并不是实例变量.
如果你运行User.find(1).instance_variables,你会看到有一个叫做iv @attributes的类型Hash.
在那里iv encrypted_password是存储的地方.Rails定义了访问器方法encrypted_password,用于获取/设置该属性的数据@attributes Hash.
请注意,您也可以通过@attributes["encrypted_password"]在User类中调用来获取/设置数据(但是访问器方法是方便的方法).