2016-07-04 68 views
2

我想我是密集这里,是因为我不断收到一个错误stack too deep ...如何避免圆形环

我有一个ChildParent关系对象。我想两件事情发生:

  • ,如果你尝试更新Child,除非它有一个Parent协会
  • 如果你创建一个Parent,然后将其连接到Child不能更新其status_id1,那么Child的状态应该自动设置为1

这里的Parent协会如何得到补充说:

parent = Parent.new 
if parent.save 
    child.update_attributes(parent_id:1) 
end 

我对Child模型这些回调:

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 

上面的代码其实并不有效,因为它是2分贝命中当理想情况下它会是1,一次完成。但我发现它太耗费脑筋,不知道为什么......我不确定为什么它甚至没有工作,因此甚至无法考虑将其作为一个单独的数据库交易。

希望这有助于澄清。想象一下Charge模型和Item模型。每个Item有一个ChargeItem也有一个属性paid。两件事情:

  • 如果更新Item,你不能更新paidtrue直到Item已与Charge对象

  • 如果通过更新链接Charge对象到Item被相关charge_id属性Item,那么代码应该为您节省时间并自动设置为paidtrue

+0

为什么你不直接循环孩子,直到父母结束? – 13aal

回答

1

这里有很多令我困惑的事,但在我看来,你在after_update和set_complete之间调用:set_complete你正在更新属性,因此你似乎有一个永久循环。可能还有其他的我看不到的循环,但是那个循环对我来说非常重要。

+0

你会如何改写它?我似乎无法想象那些有效的东西...... – james

+0

老实说,我不知道如何改写它,因为我不是100%确定你真的想要做什么。我个人需要查看更多代码才能了解所有这些的基本目的/需求。我仍然对上面的固定parent_id感到困惑。 – MageeWorld

+0

'parent_id'更新只是为了让孩子与它相关联。一个例子就是一个Charge模型和一个Item模型,其中'paid'是所讨论的属性。您不能将“Item”标记为“付费”,直到它与“Charge”对象关联。但是,一旦'Charge'对象存在,您不妨节省一些时间并自动将'Item'标记为'已付' – james

0

避免这种循环递归情况的一种方法是提供一个标志作为参数(或以其他方式)来阻止循环继续。在这种情况下(虽然我不完全清楚这个情况),我认为你可以提供一个标志来表明呼叫的起源。如果更新的来源是附加的费用,则传递一个标志来阻止检查发生,或修改它以防止发生循环。也许第二套逻辑是为了这样的情况?

0

在使用ActiveRecord回调函数时,我遇到了一个stack level too deep问题。 在我的情况下,问题是update_attribute更新通过回调后,即set_complete在您的情况下再次调用,其中update_attribute再次触发,这无止境地重复。

我通过使用update_column来解决这个问题,它不会触发任何回调或验证,但设置一个标志是更经常在线的建议。

在这一点上,我没有一个减少数据库写入操作的答案,并且如果我能想到任何东西,将会添加到这个答案中。

希望这会有帮助