设为首页 加入收藏

TOP

Callback详解(一)
2023-07-23 13:24:52 】 浏览:417
Tags:Callback 详解

Callbacks

Callback Registration

在 Rails 中,回调(Callbacks)是一种在模型对象的生命周期中执行特定代码的机制。回调可以在模型对象的创建、更新、删除等操作中执行特定的代码,例如保存对象前执行某些逻辑,或者在对象被删除前执行清理操作。

Rails 中的回调分为两种类型:前置回调(before callbacks)和后置回调(after callbacks)。前置回调在操作执行之前执行,后置回调在操作执行之后执行。可以使用 before_after_ 前缀来指定回调的类型。

以下是一些常见的回调类型:

  • before_validationafter_validation:在验证对象之前和之后执行回调。
  • before_saveafter_save:在保存对象之前和之后执行回调。
  • before_createafter_create:在创建对象之前和之后执行回调。
  • before_updateafter_update:在更新对象之前和之后执行回调。
  • before_destroyafter_destroy:在删除对象之前和之后执行回调。

要注册回调,可以在模型类中使用 before_after_ 前缀来指定回调的类型,然后指定要执行的方法:

class User < ApplicationRecord
  before_save :normalize_email

  private

  def normalize_email
    self.email = email.downcase
  end
end

在上面的例子中,我们将 normalize_email 方法注册为 before_save 回调。这意味着在保存 User 对象之前,Rails 将自动调用 normalize_email 方法。在 normalize_email 方法中,我们将 email 属性转换为小写字母,以确保所有邮件地址都是小写的。

需要注意的是,注册回调时必须指定要执行的方法的名称,可以是一个实例方法或一个类方法。回调方法中可以使用模型对象的任何属性或方法来执行特定的逻辑,例如更新其他对象、发送电子邮件等。

使用回调可以让我们更灵活地控制模型对象的行为,可以在对象的生命周期中执行任意的操作。同时,回调也可以提高代码的可读性和可维护性,使代码更易于理解和修改。

Available Callbacks

在 Rails 中,可以注册多种类型的回调来在模型对象的生命周期中执行特定代码。以下是可用的回调类型:

创建和保存对象

  • before_validation:在验证对象之前执行回调。
  • after_validation:在验证对象之后执行回调。
  • before_save:在保存对象之前执行回调,包括新建和更新操作。
  • around_save:在保存对象之前和之后执行回调,使用 yield 方法来执行保存操作。
  • after_save:在保存对象之后执行回调,包括新建和更新操作。
  • before_create:在创建对象之前执行回调。
  • around_create:在创建对象之前和之后执行回调,使用 yield 方法来执行创建操作。
  • after_create:在创建对象之后执行回调。

更新和删除对象

  • before_update:在更新对象之前执行回调。
  • around_update:在更新对象之前和之后执行回调,使用 yield 方法来执行更新操作。
  • after_update:在更新对象之后执行回调。
  • before_destroy:在删除对象之前执行回调。
  • around_destroy:在删除对象之前和之后执行回调,使用 yield 方法来执行删除操作。
  • after_destroy:在删除对象之后执行回调。

关联对象

  • before_add_association:在添加关联对象之前执行回调。
  • after_add_association:在添加关联对象之后执行回调。
  • before_remove_association:在删除关联对象之前执行回调。
  • after_remove_association:在删除关联对象之后执行回调。

其他

  • after_initialize:在实例化对象之后执行回调。
  • after_find:在从数据库中查找对象之后执行回调。

要注册回调,可以在模型类中使用相应的回调方法来指定回调的类型,然后指定要执行的方法。例如,要在保存对象之前执行特定的逻辑,可以使用 before_save 方法:

class User < ApplicationRecord
  before_save :normalize_email

  private

  def normalize_email
    self.email = email.downcase
  end
end

在上面的例子中,我们将 normalize_email 方法注册为 before_save 回调。这意味着在保存 User 对象之前,Rails 将自动调用 normalize_email 方法。在 normalize_email 方法中,我们将 email 属性转换为小写字母,以确保所有邮件地址都是小写的。

需要注意的是,回调方法中可以使用模型对象的任何属性或方法来执行特定的逻辑,例如更新其他对象、发送电子邮件等。使用回调可以让我们更灵活地控制模型对象的行为,可以在对象的生命周期中执行任意的操作。同时,回调也可以提高代码的可读性和可维护性,使代码更易于理解和修改。

回调前更新属性会怎么办

如果在回调中尝试更新属性,可能会导致一些问题。因为回调的执行顺序是不确定的,所以在某些情况下,属性的更新可能会被其他回调覆盖或被数据库中的持久化数据覆盖。

例如,如果我们在 before_save 回调中尝试更新某个属性,而在 after_save 回调中有另一个回调也尝试更新同一个属性,那么最终属性值可能会是不确定的,因为最后执行的回调会覆盖之前的值。

为了避免这种情况,应该尽量避免在回调中更新属性。如果确实需要更新属性,可以使用 update_column 方法来更新属性,该方法可以直接将属性更新到数据库中,而不触发其他回调。但是需要注意,使用 update_column 方法将跳过所有的验证,包括模型定义的验证,因此需要谨慎使用。

另外,如果在回调中需要使用其他模型对象的数据,可以将逻辑移动到控制器或服务对象中,以确保数据正确性和可维护性。

after_initialize and after_find

after_initializeafter_find 都是 ActiveRecord 模型中的回调方法。

after_initialize 方法会在创建新的 ActiveRecord 对象或从数据库中加载现有对象时被调用。该方法可以用来执行任意初始化逻辑,例如设置默认值或初始化关联对象。与其他回调不同,after_initialize 方法不需要接收任何参数,因为它是在对象创建之后立即调用的。

以下是一个示例,演示如何使用 after_initialize 方法在创建新对象时设置默认值:

class User < ApplicationRecord
  after_initialize :set_defaults

  private

  def set_defaults
    self.status |
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇关于Validation的方法使用 下一篇Ruby 的 heredoc 与 eva l

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目