如何检查生成的令牌还不存在?

时间:2016-01-21 17:54:55

标签: ruby-on-rails ruby ruby-on-rails-4

我有一个创建令牌的方法。这有效,现在我也想确保令牌的唯一性。因此我添加了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_digestapi_tokennil。并self返回:User(id: integer, email: string, username: string, fullname: string, ...。如果我将update_attributes放在begin...end(调试程序下方)中,则nilself不会返回<Userid: 1001, email: "mymail@example.com", username: "mystring1", ...

1 个答案:

答案 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