Ruby on rails 如何避免循环
我想我在这里太密集了,因为我总是得到一个Ruby on rails 如何避免循环,ruby-on-rails,ruby,ruby-on-rails-4,callback,Ruby On Rails,Ruby,Ruby On Rails 4,Callback,我想我在这里太密集了,因为我总是得到一个堆栈太深的错误 我有一个子对象和一个父对象关系对象。我希望发生两件事: 如果您试图更新子项,则无法将其状态_id更新为1,除非它具有父项关联 如果您创建一个父项,然后将其附加到子项,则子项的状态应自动设置为1 下面是如何添加父关联的: parent = Parent.new if parent.save child.update_attributes(parent_id:1) end 我在子模型上有以下回调: validate :mark_c
堆栈太深的错误
我有一个子对象
和一个父对象
关系对象。我希望发生两件事:
- 如果您试图更新
子项
,则无法将其状态_id
更新为1
,除非它具有父项
关联
- 如果您创建一个
父项
,然后将其附加到子项
,则子项
的状态应自动设置为1
李>
下面是如何添加父关联的:
parent = Parent.new
if parent.save
child.update_attributes(parent_id:1)
end
我在子模型上有以下回调:
validate :mark_complete
after_update :set_complete
# this callback is here because there is a way to update the Child model attributes
def mark_complete
if self.status_id == 1 && self.parent.blank?
errors[:base] << ""
end
end
def set_complete
if self.logistic.present?
self.update_attribute(:status_id, 1)
end
end
验证:标记完成
更新后:设置完成
#之所以出现此回调,是因为有一种方法可以更新子模型属性
def标记完成
如果self.status\u id==1&&self.parent.blank?
错误[:base]我发现这里有很多让人困惑的地方,但在我看来,你在更新之后调用:set_complete
,在set_complete
中你正在更新属性,因此你似乎有一个永久的循环。可能还有其他我看不到的循环,但我认为这是一个突出的循环。避免这种循环递归情况的一种方法是提供一个标志作为参数(或其他),以阻止循环继续
在这种情况下,(尽管我不能完全确定这个情况),我认为您可以提供一个标志,指示调用的来源。如果更新的来源是附加的费用,则传递一个标志,该标志将阻止检查的发生,或者修改它以阻止循环的发生。也许第二组逻辑适合这种情况?我在使用ActiveRecord回调时遇到了一个堆栈级别太深的问题。
在我的例子中,问题在于更新通过回调后的update\u属性
,即在您的例子中再次调用set\u complete
,在这种情况下,update\u属性
会被再次触发,并不断重复
我通过使用update\u column
解决了这个问题,它不会触发任何回调或验证,但是在网上设置一个标志是最常被建议的
在这一点上,我没有一个减少数据库写入操作的答案,如果我能想到什么,我会补充这个答案
希望这有帮助您将如何重写它?我似乎想不出什么是有效的…老实说,我不知道如何重写它,因为我不100%确定你真正想做什么。我个人需要看更多的代码来理解所有这些的潜在目的/需求。我仍然对上面固定的家长id感到困惑。parent\u id
更新只是为了让孩子与之关联。一个例子是费用
模型和项目
模型,其中付费
是所讨论的属性。在与费用
对象关联之前,您不能将项目标记为已支付。但是,一旦费用
对象存在,您还可以节省一些时间,并自动将项目标记为已支付费用
为什么不直接循环子项,直到父项结束?