如何在Rails模型中修复“ SystemStackError(堆栈级别太深)”

时间:2019-08-08 15:24:38

标签: ruby-on-rails ruby

我正在实施登录系统。我创建了用户模型,但是#before_create方法有问题。在如下所示的Rails控制台中创建新用户时,它总是会引发SystemStackError (stack level too deep)错误:

User.create(name:"othman", email: "othman@gmail.com", password: "12345678", password_confirmation: "12345678" )" 

我正在使用Rails实现登录系统,我需要在创建新用户之前记住用户令牌。

用户模型代码:

require 'digest'

class User < ApplicationRecord
  attr_accessor :token
  before_create remember


  validates :name, presence: true
  validates :email, presence: true
  has_secure_password
  validates :password, presence: true, length: { minimum: 6 }

  def remember 
    self.token = User.new_token
    update_attribute(:remember_digest , User.create_digest(token)) 
  end 

  def User.new_token
    SecureRandom.urlsafe_base64
  end 

  def User.create_digest(string)
    Digest::SHA1.hexdigest string
  end
end

错误消息:

irb(main):017:0> user1 = User.create(name:"othman", email: "othman@gmail.com", password: "12345678", password_confirmation: "12345678" )
   (0.1ms)  begin transaction
   (0.1ms)  rollback transaction
Traceback (most recent call last):
       16: from app/models/user.rb:15:in `remember'
       15: from app/models/user.rb:15:in `remember'
       14: from app/models/user.rb:15:in `remember'
       13: from app/models/user.rb:15:in `remember'
       12: from app/models/user.rb:15:in `remember'
       11: from app/models/user.rb:15:in `remember'
       10: from app/models/user.rb:15:in `remember'
        9: from app/models/user.rb:15:in `remember'
        8: from app/models/user.rb:15:in `remember'
        7: from app/models/user.rb:15:in `remember'
        6: from app/models/user.rb:15:in `remember'
        5: from app/models/user.rb:15:in `remember'
        4: from app/models/user.rb:15:in `remember'
        3: from app/models/user.rb:15:in `remember'
        2: from app/models/user.rb:15:in `remember'
        1: from app/models/user.rb:15:in `remember'
SystemStackError (stack level too deep)

1 个答案:

答案 0 :(得分:3)

您的代码中有一个before_create回调,它调用remember方法。在此remember方法中,您调用update_attribute,该方法在内部尝试save记录,该记录调用相同的before_create回调。

要解决此问题,只需使用一种方法即可设置remember_digest属性,而无需触发save

例如:

def remember 
  self.token = User.new_token
  self.remember_digest = User.create_digest(token)
end