Ruby on rails ActiveRecord中回调的排序

Ruby on rails ActiveRecord中回调的排序,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,我在ActiveRecord中订购回调时遇到一些问题。根据Rails,创建对象时回调的顺序如下: 验证前 验证后 在你保存之前 关于保存 在创建之前 围绕你创造 创建后 保存后 提交后/回滚后 我的模型中有两个回调。一个用于after_save(在创建和更新时运行),另一个用于after_create。在创建时,我希望仅在保存后回调后运行创建后回调。如何在ActiveRecord中完成此操作?谢谢。不要更改rails的行为回拨-即使您知道如何回拨,也会使以后在应用程序上工作更加困难-更改代码

我在ActiveRecord中订购回调时遇到一些问题。根据Rails,创建对象时回调的顺序如下:

  • 验证前
  • 验证后
  • 在你保存之前
  • 关于保存
  • 在创建之前
  • 围绕你创造
  • 创建后
  • 保存后
  • 提交后/回滚后

我的模型中有两个回调。一个用于after_save(在创建和更新时运行),另一个用于after_create。在创建时,我希望仅在保存后回调后运行创建后回调。如何在ActiveRecord中完成此操作?谢谢。

不要更改rails的行为
回拨
-即使您知道如何回拨,也会使以后在应用程序上工作更加困难-更改代码的放置位置

你对
回拨电话的名字太在意了
。他们什么时候跑步更重要

以下是我们对您的设计的了解,无需假设实现它的最佳方式

  • 您有一个在创建新记录后运行的方法
  • 您有一个在更新旧记录后运行的方法
在这里,为了使编程更容易,您似乎改变了设计决策,但这样做违反了最佳实践

  • 出于某种原因,您认为更新的方法应该每次都运行(
    在保存之后),而不是在更新之后运行
  • 出于某种原因,您认为创建方法应该在更新方法之后运行(这是一种不健康的代码链接)
从技术上讲,创建和更新所需的部分应分为第三种方法,并由创建后的
和更新后的
调用,这样您的代码就可以记录自己,并且更容易理解

所有这些都是相对重要的——正如大多数经验丰富的程序员强调的那样,只有在没有其他合理方法的情况下才应该使用
回调
——因为在解决模糊问题时,它们很难概念化


解决方案1-轨道方式

after_save
应仅用于需要为更新和创建运行的代码。任何需要为一个或另一个运行的代码都应该用较小的方法分解,然后在更新后调用
,在创建后调用
,以保持干燥

解决方案2和3在不改变设计的情况下重构旧代码

  • 设置一个工作测试,以确保您的代码在您期望的地方失败并成功
  • 保存后必须运行
    ,因此我们知道它必须在那里。我们用一个名为“update\u method\u code”的方法来封装它
    
  • 将“更新方法代码”的方法定义移动到模型或服务对象中的某个位置
  • 保存后,在
    中保留对“更新\u方法\u代码”的方法调用
    因为我们在技术上没有改变任何东西,所以测试应该是绿色的

  • 您以前在创建后的
    中进行编码-将其包装在名为“新建对象\u code”的方法中,以便对其进行封装
    
  • 将“新对象”代码的方法定义移动到模型或服务对象中的某个位置 这是你有几个选择的地方

    • 您可以使用以下四种方法之一进行“更新方法\u代码””测试 要测试,请调用该方法 “新对象代码”。这不好,因为它会造成可见性问题 也就是说,如果一个失败了,其余的都失败了。以一种非常严厉的方式 确保“新对象代码”的条件仅在 “更新方法代码”

    • 您可以使用已经构建的Rails方法<代码>保存后:更新方法\u代码on::create
  • 以触发“更新方法\u代码””。参见这里的示例。请记住,即使您的另一个
    after\u save
    调用没有。。。因此,再次强调,这种方法比简单地按照Rails的方式&在更新之后使用
    /
    在创建之后使用
    更为合理



  • 祝你的项目好运

    嗯,您不能重新排序回调。因此,要么在保存后将逻辑放入
    (或更高版本),要么完全使用回调。例如,支持某种生成器模式。我认为这样做没有任何意义,因为
    rails-3
    rails-5
    应用程序升级会改变调用顺序。因此,@SergioTulentsev建议的更改是有效且可取的。@SergioTulentsev如何在创建后将
    逻辑添加到保存后的
    中<“保存后的代码”
    也将在更新时运行。@BKS:在我的头上,您可以在创建前的
    中设置一个标志。”。类似于
    self.record\u的内容刚刚创建=true
    。然后在保存后在
    中选中此标志。如果标志为true,则运行“创建特定零件”命令。我,我会将其提取到单独的生成器/更新对象中。应该使构建过程显而易见。需要时可以避免。@BKS您可以使用
    new\u record?
    检查记录是否是新的。因此,在保存后回拨检查中,请选择“新建记录”