我在“睡眠”和“ 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:堆栈级别太深
答案 0 :(得分:1)
堆栈级别太深表示它进入了无限循环。如果您在保存之前,保存之后,创建之前,创建之后,更新之前,更新之后再次调用回调保存任何内容,则会导致堆栈级别太深。
在上面的代码中,我发现set_st_point在创建和保存之前被调用,这导致此处的堆栈级别太深。设置后数据未保存,这还必须是其他一些问题,您必须检查一下是否将“ lonlat”设置为其他位置是否正在重置它。
创建后便可以进行简单修复了
.update_column('lonlat',"POINT(#{longitude} #{latitude})")
更新列将不会调用创建后必须存在的任何回调。