我有一个创建令牌的方法。这有效,现在我也想确保令牌的唯一性。因此我添加了while self.class.exists?(api_digest: api_digest)
(见下文)。但是,现在各种测试都失败并出现错误:
ArgumentError:参数数量错误(0表示2)
引用会话助手中的def remember_api(type, user)
。我有什么想法吗?
用户模型:
def remember_api
self.api_token = User.new_token # Creates new api_token.
update_attributes(api_digest: User.digest(api_token), api_sent_at: Time.zone.now)
end while self.class.exists?(api_digest: api_digest)
def User.new_token
SecureRandom.urlsafe_base64
end
def User.digest(string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end
会话助手:
def remember_api(type, user)
if type == "user"
user.remember_api
end
end
更新:所以我尝试了以下方法。但是,这似乎不起作用,因为它进入无限循环。
def remember_api
begin
self.api_token = User.new_token
update_attributes(api_digest: User.digest(api_token), api_sent_at: Time.zone.now)
end while self.class.exists?(api_digest: api_digest)
end
Update2:我在api_digest
上获得了唯一性的模型验证,并尝试了以下内容:
def remember_api
begin
self.api_token = User.new_token
api_digest = User.digest(api_token)
debugger
end until update_attributes(api_digest: api_digest, api_sent_at: Time.zone.now)
end
这是错误的,再次创建一个无限循环。它证明,一旦我将update_attributes
移到end
后面,调试器就会显示api_digest
和api_token
为nil
。并self
返回:User(id: integer, email: string, username: string, fullname: string, ...
。如果我将update_attributes
放在begin...end
(调试程序下方)中,则nil
和self
不会返回<Userid: 1001, email: "mymail@example.com", username: "mystring1", ...
。
答案 0 :(得分:1)
第二个api_digest
应为self.api_digest
。这是因为它正在寻找一个名为api_digest的局部变量,但你的意思是这个模型的属性
像这样:
def remember_api
begin
self.api_token = User.new_token
update_attributes(api_digest: User.digest(api_token), api_sent_at: Time.zone.now)
end while self.class.exists?(api_digest: self.api_digest)
end
<强>更新强>
当您致电update_attributes
时,如果更新并通过验证,则会返回true。然后它会继续检查它是否存在并确实存在,因为你刚刚更新它,所以它会再次循环并导致无限循环
如果update_attributes
返回false,则表示它存在并满足while语句和循环。这是它唯一一次达到你的预期。
begin
self.api_token = User.new_token
self.api_digest = User.digest(api_token)
end while self.class.exists?(api_digest: self.api_digest)
self.api_sent_at = Time.zone.now
self.save!
Doc:update