ruby-on-rails - rails 上的 ruby 。堆栈级别太深错误

标签 ruby-on-rails model

堆栈级别太深错误导致我的应用程序崩溃。 我有一个包含两行的存款模型:收入和现金支出。 这两行由收入和提款模型中的 after_create 回调修改。 在提款模型中,我想使用 before_create 回调来验证存款余额(创建提款后存款余额必须大于或等于 0)并收到错误消息: CashoutsController#create 中的 SystemStackError。

ps:收入回调正常。

代码:

存款.rb

class Deposit < ActiveRecord::Base
    belongs_to :user
    has_many :incomes
    has_many :cashouts
end

架构.rb

...

  create_table "deposits", force: true do |t|
    t.integer  "user_id"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.decimal  "income",     precision: 12, scale: 2
    t.decimal  "cashout",    precision: 12, scale: 2, default: 0.0
  end

提现.rb

class Cashout < ActiveRecord::Base
    belongs_to :deposit
    validates :deposit_id, :order_sum, presence: true
    validates :order_sum, numericality: true
    validates :order_sum, numericality: { greater_than_or_equal_to: 0}
    before_create :validate_order #before_save crashed too
    after_create :update_deposit_cashout # working fine

    private

    def validate_order
        @deposit = self.deposit
        @income = @deposit.income
        @cashout = self.order_sum
        if @income - @cashout >= 0
            self.save
        else
            !self.save
        end
    end

    def update_deposit_cashout
        @deposit = self.deposit
        @deposit.update_attributes(:cashout => @cashout + self.order_sum)
    end
end

cashouts_controller.rb

class CashoutsController < ApplicationController
  before_action :signed_in_user, only: [:create]
  
  def new
    @cashout = @deposit.cashouts.build
  end

    def create
    @deposit = current_user.deposit
    @cashout = @deposit.cashouts.build(cashout_params)
    @cashout.save 
    if @cashout.save
      flash[:success] = "Your order request has been sent!"
      redirect_to '/deposit'
    else
      flash[:error] = "Your order request hasn't been sent!"
      redirect_to '/deposit'
    end
  end

  def show
    @deposit = Deposit.find(params[:id])
    @deposit.cashout
  end


  private

    def cashout_params
      params.require(:cashout).permit(:order_sum)
    end
    
end

收入.rb

class Income < ActiveRecord::Base
    belongs_to :deposit
    validates :deposit_id, :order_sum, presence: true
    validates :order_sum, numericality: true
    validates :order_sum, numericality: { greater_than_or_equal_to: 0}

    after_create :update_deposit_income

    private

    def update_deposit_income
        @deposit = self.deposit
        if @deposit.income == nil
            @income = 0
        else
            @income = @deposit.income
        end
        @deposit.update_attributes(:income => @income + self.order_sum)
    end
end

收入 Controller .rb

class IncomesController < ApplicationController
  before_action :signed_in_user, only: [:create]
  
  def new
    @income = @deposit.incomes.build
  end

    def create
    @user = current_user
    @deposit = @user.deposit
    @income = @deposit.incomes.build(income_params) 
      @income.save
    if @income.save
      flash[:success] = "Your order request has been sent!"
      redirect_to '/deposit'
    else
      flash[:error] = "Your order request hasn't been sent!"
      redirect_to '/deposit' if current_user.present?
    end
  end

  def show
    @deposit = Deposit.find(params[:id])
    @deposit.income
  end


  private

    def income_params
      params.require(:income).permit(:order_sum)
    end
    
end

我的错误在哪里?

最佳答案

stack level too deep 错误通常是因为您的代码陷入了循环:要么是一个方法调用自身,要么是两个方法反复相互调用。

在您的情况下,我认为这是由 validate_order 方法引起的。您在 before_save 回调中调用它,该方法调用 self.save,这将触发回调,这将再次调用该方法,这将再次保存,这会触发回调等等。

想一想 - 将对象保存为“before_save”功能的一部分没有意义,对吗?

我怀疑你想做的只是验证对象,如果验证失败,无论如何都会自动阻止保存。像这样

validate :validate_order

def validate_order
  @deposit = self.deposit
  @income = @deposit.income
  @cashout = self.order_sum
  if @income - @cashout <= 0
    self.errors.add(:deposit, "is too small")
  end
end

这只是一个示例,因为我不知道您正在测试的实际逻辑应该是什么。

关于ruby-on-rails - rails 上的 ruby 。堆栈级别太深错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32045253/

相关文章:

ruby-on-rails - Wicked Wizard Controller 中的非静态操作

ruby-on-rails - 抑制 Rspec 3 的回溯

ruby-on-rails - 自动加载一堆小类

ruby-on-rails - rails : Displaying different view for the same URL?

javascript - 如何在 Ember js 中获取 currentRouteName 的动态部分

ruby-on-rails - 模型中的自定义验证

javascript - 将 JSON 从索引操作提供给公共(public)文件夹中的 index.html

types - 无法在 Ember 模型中为数字和字符串类型设置默认值

ruby-on-rails - 覆盖gem中的模型,添加回调和方法

django - 如何获取 Django 模型的应用程序?