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
更新只是为了让孩子与之关联。一个例子是
费用
模型和
项目
模型,其中
付费
是所讨论的属性。在与
费用
对象关联之前,您不能将
项目标记为已支付
。但是,一旦
费用
对象存在,您还可以节省一些时间,并自动将
项目标记为已支付
费用
为什么不直接循环子项,直到父项结束?