2016-07-04 74 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來解決這個問題,它不會觸發任何回調或驗證,但設置一個標誌是更經常在線的建議。

在這一點上,我沒有一個減少數據庫寫入操作的答案,並且如果我能想到任何東西,將會添加到這個答案中。

希望這會有幫助