验证器内的增量字段

时间:2017-09-04 01:36:56

标签: ruby-on-rails activerecord

我有一个自定义验证程序,用于检查用户是否输入了正确的SMS代码。当用户输入错误的代码时,我需要记录失败的尝试并将其重试限制为每个代码3个。

我创建了以下验证器,但该字段没有递增。

  def token_match
    if token != User.find(user_id).verification_token
      User.find(user_id).increment!(:verification_fails)
      errors.add(:sms_code, "does not match")
    end
  end

问题是我在添加错误后立即回滚前一个语句。如果我注释掉errors.add行,那么增量就会起作用,但是没有执行更高级别的验证。

2 个答案:

答案 0 :(得分:0)

您可以在验证程序中使用#update_columns。它直接写入db。

u = User.find(user_id)
u.update_columns(verification_fails: u.verification_fails + 1)

这对我有用。但如果由于某种原因它不能为你工作,也许你可以尝试在一个新的线程中运行它,这会创建一个新的数据库连接:

Thread.new do
  num = User.find(user_id).verification_fails
  ActiveRecord::Base.connection_pool.with_connection { |con| con.exec_query("UPDATE users SET verification_fails = #{num} WHERE id = #{user_id}") }
end.join

答案 1 :(得分:0)

将自定义验证程序更改为:

  def token_match
    if token != User.find(user_id).verification_token
      errors.add(:sms_code, "does not match")
    end
  end

并在模型中添加after_validation回调,如下所示:

after_validation: increase_fails_count

    def increase_fails_count
      unless self.errors[:sms_code].empty?
        user = User.find_by(:id => user_id)
        user.increment!(:verification_fails)
        user.save
      end
    end