【问题标题】:Rails 3: Ensure before_save callback is called after othersRails 3:确保在其他人之后调用 before_save 回调
【发布时间】:2012-05-31 17:23:47
【问题描述】:

有没有办法确保在 ActiveRecord 中的所有其他 before_save 回调之后执行给定的 before_save 回调,而不是在代码中实际对它们进行排序?

我正在编写一个包含一些 before_save 功能的外部库,但为了有效,它确实需要在所有其他库之后调用。我可以绕过它,但它涉及放弃我真的不想放弃的肮脏属性!

-- 编辑--

我没有意识到在保存模型后会保留脏属性。所以@page.attribute_was 在yield 之后仍然可以在around_save 中工作。

【问题讨论】:

    标签: ruby ruby-on-rails-3 activerecord


    【解决方案1】:

    您可以将要执行的回调设为最后一个 around_save 回调。查看list of available 回调,看看您是否可以简单地为某些回调使用不同的回调“桶”,以确保它们以所需的顺序执行。

    如果您仍然有多个 before_save 回调并且需要最后一个触发,您可能想要创建自定义回调,例如 define_model_callbacks :split_save,将您的常规 before_save 回调注册为 before_split_save 回调,即您希望最后作为 after_split_save 回调执行,然后只运行一个 before_save 回调来运行这两组回调 (run_callbacks :split_save)。有关如何执行此操作的更多信息,请参阅ActiveModel::Callbacks。

    【讨论】:

    • 谢谢卡尔。我曾尝试使用around_save 并将我的代码放在yield 之前,但是在它之后仍然调用了一些before_saves。我无法解决。明天我一定会看看 ActiveModel::Callbacks 并报告。
    • @JonHope 是的,我从未真正使用过around_save。查看文档,它似乎应该总是在 before_save 回调之后触发,但是“around”回调的工作方式有点不同,所以我可能误解了。可能想尝试将除最后一个要执行的回调之外的所有回调设置为after_validation 回调,最后一个为before_save。自定义回调也可以,但after_validation 可能会为您省力。
    • 谢谢卡尔。不幸的是,我不能使用自定义回调,因为我需要 gem 作为一个插入式解决方案,我不能让人们更改他们的回调代码。我的思路是找到回调数组并在对象保存之前手动将我的添加到末尾。这是一个观众吗?
    【解决方案2】:

    所以这是通过使用有序的before_<type> 回调而不是after_<type> 回调来绕过放弃脏属性,因为脏属性changes 在保存后会被擦除。

    然而,changes 仍然可以在 after_<type> 回调中访问。

    我只是在浏览Vestal Versions 代码以了解他们是如何做到的之后才解决这个问题的。

    捂脸。

    我接受 Carl 的回答,因为它是对相当糟糕的问题的相当完整的回答。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-14
      • 1970-01-01
      • 1970-01-01
      • 2014-05-29
      相关资源
      最近更新 更多