2016-07-07 62 views
1

我知道,保存模型的一般顺序是最深的孩子,然后逐渐上升到父母。但我相对于其他的回调不知道,它发生的线沿线的东西:嵌套父/子模型的模型回调以什么顺序运行?

ChildA - before validation 
ChildB - before validation 
Parent - before validation 

ChildA - after validation 
ChildB - after validation 
Parent - after validation 

ChildA - before save 
ChildB - before save 
Parent - before save 

... 

或沿的线条:

ChildA - before validation 
ChildA - after validation 
ChildA - before save 
... 

ChildB - before validation 
ChildB - after validation 
ChildB - before save 
... 

Parent - before validation 
Parent - after validation 
Parent - before save 
... 

的原因,这是非常重要的是,我有回调调整属性,模型上属性的可调整性取决于其他模型的属性。

一个例子是,我想向Parent自动设置其属性statusComplete如果ChildAchild B's状态attributes are both完全and the children are both valid`。

我试图用puts声明来测试这个语句,但很明显,这会导致一些奇怪的行为(请参阅此问题:Nested form validation statements repeating multiple times),恐怕它不具有代表性。

我肯定读了Rails指南,但也许我瞎了,因为我没有看到这个随时随地的参考...

+0

你有没有找到答案? – geoboy

回答

0

,而把这种状态机逻辑的回调可能是诱人的,这使得代码难以理解。请考虑采用一种专用的方法,以更直接的方式收集和变更数据。

这也与数据的一致性和测试帮助,如this blog post描述。

+0

谢谢!现在,未来需要考虑的事情就是需要一些快速和肮脏的东西 – james

0

有趣的问题。默认情况下,父级中定义的回调将首先运行。 prepend: true选项允许您调整该行为。

见 “定货回调” 一节中Rails API。同样值得检查“可继承回调队列”部分,因为重新定义方法与使用宏不同。

P.S.所有上述有效期至少为4.2.5.2

0

版本通过与我曾经遇到过父被验证,然后再孩子,但没有护栏的核心成员已经宣布这个轨试验。

这就是为什么你可以移动的逻辑父:

class Sale 
    has_many :details 
    before_validation :evaluate_details 
    # validations 

    def evaluate_details 
    self.details.each do |detail| 
     detail.generate_info 
     detail.items.each do |item| 
     item.dance 
     end 
    end 
    end 
end 

class Detail 
    belongs_to :sale 
    has_many :items 
    # validations 

    def generate_info 
    # Do things 
    end 
end 

class Item 
    belongs_to :detail 
    # validations 

    def dance 
    # Dancing 
    end 
end 

这样可以防止多个执行和管理的执行顺序。

PD:您也可避免before_validation回调并手动调用该方法。