Rails 5.1.6出现Stack level too deep错误求助(附控制器代码)
解决Rails中Stack level too deep错误的方案
你遇到的栈溢出问题,根源在于create方法里的重复保存操作,加上不必要的参数传递引发的潜在循环触发。让我一步步帮你分析和修复:
问题分析
你的create方法里做了这两步:
@scan = @device.scans.create(scan_params) flash[:notice] = t('.success') if @scan.save
核心问题是:create方法本身就会自动执行save操作,紧接着你又手动调用@scan.save,相当于对同一个对象连续触发两次保存流程。如果你的Scan模型里有回调(比如before_save、after_save),这种重复操作很容易引发递归调用,最终导致栈溢出。
另外,你的scan_params里允许了:device_id参数,但你已经通过@device.scans.create的方式关联了设备,这个参数完全多余,甚至可能在赋值时触发关联的额外回调,加重循环风险。
修复方案
1. 调整create方法的保存逻辑
把create换成build,手动控制保存流程,避免重复操作:
def create @scan = @device.scans.build(scan_params) if @scan.save flash[:notice] = t('.success') end respond_with @scan.device, @scan end
build只会初始化对象,不会自动保存,这样你可以通过一次save完成操作,逻辑更清晰,也避免了重复触发回调。
2. 移除不必要的device_id参数
修改scan_params,去掉:device_id,因为关联已经通过@device.scans.build自动设置:
def scan_params params.require(:scan).permit(:photo, :reading, :reading_date) end
这不仅能避免潜在的循环问题,还能防止前端恶意修改关联的设备,提升安全性。
3. 检查模型回调(额外排查)
如果修改后还是出现栈溢出,建议检查Scan模型里的回调函数,看看有没有类似下面的递归逻辑:
after_save :do_something def do_something self.save # 这里会再次触发save,形成循环 end
如果有这类代码,需要调整回调逻辑,避免重复触发保存。
内容的提问来源于stack exchange,提问作者Antronin
相关产品推荐
相关产品推荐

