首页 > 解决方案 > 保存前回调:SystemStackError:堆栈级别太深

问题描述

我有一个多态关系 beewten “sleeps” 和 “pois”。

class Sleep < ApplicationRecord
  has_one :poi, as: :poitable, dependent: :destroy
  accepts_nested_attributes_for :poi

在我的睡眠控制器中:

 def create
   @sleep = Sleep.new(sleep_params)
   @sleep.user_id = current_user.id if current_user
   if @sleep.save
     redirect_to track_sleeps_path, notice: t(".sleep_created")
   else
    render :new
   end
 end

和参数:

 def sleep_params
   params.require(:sleep).permit(
    :name,
    .......,
    { :poi_attributes => [..., :latitude, :longitude, :lonlat, :poitable_id, :poitable_type] } )
 end

我的 Poi 控制器:

class Poi < ApplicationRecord
  geocoded_by :full_address
  after_validation :geocode, if: :will_save_change_to_address?
  before_create :set_st_point
  belongs_to :poitable, polymorphic: true, optional:true

当我创建一个新实例时,我通过地理编码器获得经度和纬度。它工作正常。

但我想通过函数 set_st_point 设置 lonlat

  def set_st_point
    if latitude.present? && longitude.present?
      self.lonlat = "POINT(#{longitude} #{latitude})"
    end
  end

我一直在尝试“before_save”、“before_create”,但字段 lonlat 保持为空。

我该如何解决这个问题?

编辑 :

我正在尝试做:

  def set_st_point
    if latitude.present? && longitude.present?
     self.lonlat = "POINT(#{longitude} #{latitude})"
     self.save!
   end
  end

但是现在,我有一个 SystemStackError: stack level too deep

标签: ruby-on-railscallback

解决方案


堆栈级别太深表示它进入了无限循环。如果您在保存前、保存后、创建前、创建后、更新前、更新后再次调用回调将导致堆栈级别太深。

在上面的代码中,我发现在创建和保存之前调用了 set_st_point,这导致这里的堆栈级别太深。设置后数据未保存也必须是其他问题,您必须检查一旦您在其他地方设置了“lonlat”,它是否正在重置它。

在创建后进行简单修复后,您可以说

 .update_column('lonlat',"POINT(#{longitude} #{latitude})")

更新列不会调用任何回调,这必须在创建后存在。


推荐阅读