我有点卡住试图从 Rails 中的自定义设置器访问(读取)属性:
def password=(new_password)
puts self.firstname # returns nil
# Do other checks here before setting a hashed SCrypt password
end
名字是在(用户)对象上定义的,但是调用名字不会产生值集。我需要从自定义设置器中读取各种属性,以针对名字、姓氏和电子邮件地址进行密码检查。
我有点卡住试图从 Rails 中的自定义设置器访问(读取)属性:
def password=(new_password)
puts self.firstname # returns nil
# Do other checks here before setting a hashed SCrypt password
end
名字是在(用户)对象上定义的,但是调用名字不会产生值集。我需要从自定义设置器中读取各种属性,以针对名字、姓氏和电子邮件地址进行密码检查。
你有对应的getter方法吗?
def password
@password
end
或者,如果它是一个非常简单的 getter/setter 对
:attr_accessor password
更新您的评论:所以您想要做的不仅仅是在 setter 中设置属性?
所以很明显,我必须反对这一点。但是,您可以执行以下操作:
def password=(new_password)
some_method(new_password)
@password = new_password
end
这会将 new_password 方法从 setter 中传递出去,允许您在将实例变量设置为新值之前用它做其他事情。
如果您尝试访问密码设置器中的 firstname 属性,如您的示例中所示,您可以这样做:
def password=(new_password)
some_method(firstname)
@password = new_password
end
您不使用 self 来调用 getter 方法。
好的似乎是我的应用程序某处的问题。我刚刚做了一个运行良好的最小测试应用程序:
class User < ActiveRecord::Base
def password
password ||= SCrypt::Password.new(password_hash)
end
def password=(new_password)
logger.info 'DEBUG: self.lastname: ' + self.lastname.to_s
self.password_hash = SCrypt::Password.create(new_password, :key_len => 512, :salt_size => 32)
end
end
在控制台中它工作正常:
Loading development environment (Rails 3.2.12)
2.0.0-p0 :001 > u = User.new
=> #<User id: nil, firstname: nil, lastname: nil, password_hash: nil, created_at: nil, updated_at: nil>
2.0.0-p0 :002 > u.lastname = "Some Lastname"
=> "Some Lastname"
2.0.0-p0 :003 > u.password = 'test'
DEBUG: self.lastname: Some Lastname
=> "test"
因此,这似乎是与应用程序中的 gem / something / 某处相关的问题,而不是 Rails 特定的问题。向名单道歉。
根据我的观察,参数的顺序在这里很重要。
⚠️注意通过的顺序:firstname
和:password
时间。
如果您正在使用params.require(:user).permit(:firstname, :password)
然后通过.new
or=setter
方法将其传递给您的设置器。然后,您始终可以self.firstname
在您的password=
setter 方法中访问,因为您firstname
首先获得了设置,并且可以访问下一个 setter。
但是,如果您有,params.require(:user).permit(:password, :firstname)
那么您的密码设置方法将无法访问self.firstname
.