2012-02-14 70 views
1

我们有小班,具有相关类rails 3.2:after_update在销毁元素时也被调用?

class Car 
    has_one :engine, :dependent => :destroy 

    after_update :save_engine 


    delegate :oil_level, :oil_level=, :to => :engine 

    def save_engine 
    engine.save if engine 
    end 
end 

正如你所知道的,我们正在努力工作,围绕孩子的不会自动保存在轨道的问题。所以我们可以在车上设置oil_level,并且在保存时将它正确地存储在engine中。

现在当我们尝试删除汽车时会发生什么?显然engine永远不会被删除,这是由after_update,这将重新保存刚刚删除的引擎造成的。所以汽车被成功删除,但引擎被重新创建(一个新的ID),并不再与汽车相关联。我想要正确删除引擎。

我没有找到一个坚实的变通:

class Car 
    has_one :engine, :dependent => :destroy 

    after_update :save_engine 
    before_destroy :set_destroying 


    delegate :oil_level, :oil_level=, :to => :engine 

    def set_destroying 
    @destroying = true 
    end 

    def save_engine 
    engine.save if engine && [email protected] 
    end 
end 

但它仍然感觉有点脏,好像应该有更好的方式来做到这一点。 破坏时调用after_update似乎有点不合逻辑。 是否有一个特定的轨道方式来知道回调(保存/创建/销毁)中实际进行的操作?简而言之:什么是正确的方法来处理这个问题?或者这实际上是一些轨道bug?或者这是预期的行为?

回答

1

有一段时间没有完成Rails,所以我可能会脱离主题,但是您有没有考虑使用:autosave选项?

+0

这听起来像它可能正是我所需要的。我会尝试这个,并让你知道。谢谢。 – nathanvda 2012-02-14 20:30:03

0

1)确保在car_controller def destroy中调用car.destroy NOT car.delete,否则回调将被忽略,引擎不会被销毁。

2)引擎是否被删除(相同的id)或被重新创建? (diff ID),你似乎在你的描述中从一个跳到另一个。

+0

是的我打电话'car.destroy',引擎用不同的id重新创建。我澄清了一下我的问题。我的解决方法确实有效,所以我有一个工作解决方案,但我怀疑应该有更好的方法。 – nathanvda 2012-02-14 09:32:16

+0

嗡嗡声,我想我在这个失败了,因为我没有达到3.2的标准,但我希望委托的功能类似于car.engine.build(),这意味着在引擎上调用save汽车被保存。我可以用另一种方式将其写成干净的,但除此之外,我只需切换钩子的顺序:before_update:save_engine after_destroy:set_destroying – TomDunning 2012-02-14 20:23:22

+0

嗯,您似乎完全不了解我的问题。我的钩子很好,工作。问题是:在销毁我的汽车时也会调用'after_update',这会保存我的引擎(再次),这应该被':dependent =>:destroy'删除。所以在'before_destroy'中我设置了开关,所以在销毁时我不会保存引擎。这样可行。所以钩子的顺序是正确的。但是:你知道更清洁的方式吗?为什么在销毁时还会调用'after_update'?而不是设置'@ destroying'是否有更清晰的方式来知道我们在回调中被摧毁? – nathanvda 2012-02-14 20:33:25

相关问题