我有点试图从Rails中的自定义setter访问(读取)一个属性:
def password=(new_password)
puts self.firstname # returns nil
# Do other checks here before setting a hashed SCrypt password
end
firstname是在(user)对象上定义的,但是调用firstname不会产生值集。我需要从自定义setter中读取各种属性,以便根据firstname,lastname和email地址进行密码检查。
答案 0 :(得分:0)
你有相应的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方法。
答案 1 :(得分:0)
好的,似乎是我的应用程序的问题。我刚做了一个很好的最小测试应用程序:
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特定的问题。向列表道歉。
答案 2 :(得分:0)
根据我所观察到的,参数的顺序在这里很重要。
⚠️传递时请注意:firstname
和:password
的顺序。
如果您使用的是params.require(:user).permit(:firstname, :password)
,然后通过.new
或=setter
方法将其传递给设置器。然后,您总是可以使用self.firstname
的setter方法访问password=
,因为您firstname
首先被设置,并且可以访问下一个setter。
但是,如果您拥有params.require(:user).permit(:password, :firstname)
,则您的密码设置方法将无法访问self.firstname
。