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

Oth*_*ani 2 ruby ruby-on-rails

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

User.create(name:"othman", email: "othman@gmail.com", password: "12345678", password_confirmation: "12345678" )" 
Run Code Online (Sandbox Code Playgroud)

我正在使用 ruby​​ on 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
Run Code Online (Sandbox Code Playgroud)

错误信息:

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)
Run Code Online (Sandbox Code Playgroud)

spi*_*ann 6

在您的代码中有一个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 
Run Code Online (Sandbox Code Playgroud)