Callbacks 回调

基于 Action Model 提供的 define_model_callbacks 和 Active Support 提供的 define_callbacks 方法,共生成十几个过滤器方法。

# ActiveRecord::Callbacks
define_model_callbacks :initialize, :find, :touch, :only => :after
define_model_callbacks :save, :create, :update, :destroy

# ActiveModel::Callbacks
define_callbacks :validation

# ActiveRecord::Transactions
define_callbacks :commit, :rollback

和 AbstractController::Callbacks::ClassMethods 用元编程生成过滤器的方法名,是两种手法(尽管最终都是基于 ActiveSupport::Callbacks).

是什么?

通过钩子的方式,影响对象的生命周期。

有哪些?

共 22 个:

CALLBACKS = [
  :after_initialize, :after_find, :after_touch,
  :before_save, :around_save, :after_save,
  :before_create, :around_create, :after_create,
  :before_update, :around_update, :after_update,
  :before_destroy, :around_destroy, :after_destroy,
  :before_validation, :after_validation,
  :after_commit, :after_rollback,

  :after_create_commit, :after_update_commit, :after_destroy_commit
]

怎么使用?

调用方式主要有以下几种:

  1. 宏定义的方式,后面跟方法名进行调用

  2. 传递一个可回调对象

  3. 以类方法的形式,传递一个 block

1、3 用得最多,第 2 次之,还有一种方法不推荐(以字符串的形式传递),第 2 可以起到分离和复用的作用,但复杂度提高了,并且有其它实现手法可替代。

回调是针对单个 record 对象而言的。当传递给回调的参数是一个实例对象时,把当前 record 对象当做参数,传递并执行实例对象里和回调同名的方法。创建实例对象的时候,你也可以传递参数。

抽取封装回调方法

覆盖方法名,重新定义方法内容(注意:这里定义的是实例方法啊,内容不会被执行,其它类再继承才能执行!)

怎么取消后面的回调?

在方法里返回 false

如何理解 around

用 around_save 举例:

一个生命周期为一个事务(BEGIN...COMMIT)

如果没有特殊操作,一个生命周期里,对数据库的操作是在同一个“事务”里进行的。所以,如果中间的失败,返回 false 那么后续操作,甚至前面的操作都会失败。

开发里,可以在控制台或日志里查看 BEGIN...COMMIT 之间的增删查改语句,确保同一个事务里您的操作是预期的。

最后更新于

这有帮助吗?