当前位置:首页 > 后端开发 > 正文内容

Callback详解

邻居的猫1个月前 (12-09)后端开发1561

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 ||= "active"
  end
end

在上面的比如中,咱们将 set_defaults 办法注册为 after_initialize 回调。在 set_defaults 办法中,咱们检查 status 特点是否为 nil,假如是,则将其设置为默认值 "active"

after_find 办法会在从数据库中查找 ActiveRecord 目标之后被调用。该办法能够用来履行恣意的后处理逻辑,例如核算特点或更新相关目标。after_find 办法接纳一个参数,即从数据库中加载的 ActiveRecord 目标。

以下是一个示例,演示怎么运用 after_find 办法核算用户的年纪:

class User < ApplicationRecord
  after_find :calculate_age

  private

  def calculate_age
    self.age = Date.today.year - birthday.year
  end
end

在上面的比如中,咱们将 calculate_age 办法注册为 after_find 回调。在 calculate_age 办法中,咱们运用从数据库中加载的用户目标的生日特点核算用户的年纪,并将成果保存到年纪特点中。

需求留意的是,after_find 办法只会在从数据库中加载目标时被调用,而不会在实例化新目标时被调用。假如需求在目标创立后履行某些逻辑,应该运用 after_initialize 办法。

after_touch什么 意思

after_touch是Rails中的一个回调办法,它会在一个已相关的目标被touch操作更新后被触发。在Rails中,touch操作指的是在更新一个目标时,一起更新相关目标的更新时刻戳(updated_at)字段。这个操作能够用来完成缓存失效、从头核算统计数据等功能。

例如,假定你有一个User模型和一个Post模型,一个用户能够具有多篇文章。当你更新某篇文章时,你或许需求更新相关用户的更新时刻戳,以便在用户列表或其他地方正确地排序。你能够运用touch选项来完成这一点,如下所示:

class Post < ApplicationRecord
  belongs_to :user, touch: true
end

class User < ApplicationRecord
  has_many :posts
  after_touch :update_sorting

  def update_sorting
    # 更新用户排序,例如更新`updated_at`字段
    self.touch
  end
end

这段代码界说了两个Active Record模型,PostUser,它们之间存在一个一对多的相相关系。

Post模型中,运用belongs_to :user, touch: true声明晰一个归于相关,表明一篇文章归于一个用户。touch: true选项表明当文章被更新时,主动更新与之相关的用户的updated_at字段,以便在用户列表或其他地方正确地排序。

User模型中,运用has_many :posts声明晰一个具有多个相关,表明一个用户能够具有多篇文章。after_touch :update_sorting声明晰一个after_touch回调办法,表明当与之相关的一篇文章被touch操作更新时,主动调用update_sorting办法更新用户排序,例如更新updated_at字段。

update_sorting办法中,运用self.touch办法更新用户的updated_at字段,以便在用户列表或其他地方正确地排序。

需求留意的是,这段代码中运用了touch操作来完成主动更新相关目标的更新时刻戳,这能够用来完成缓存失效、从头核算统计数据等功能。在Rails中,touch操作是一种常见的技巧,能够用来简化代码并进步性能。

需求留意的是,after_touch回调办法只会在touch操作触发更新时被调用。假如你手动更新了updated_at字段,after_touch回调办法不会被调用。

运转回调

这些是Rails中常用的Active Record模型操作办法,下面别离介绍它们的效果:

  1. create(attributes = {}):创立一个新的模型目标并将其保存到数据库中。能够传入一个哈希表参数attributes表明要创立的模型目标的特点值。

  2. create!(attributes = {}):与create相同,但假如保存失利会抛出反常。

  3. destroy:从数据库中删去当时模型目标。

  4. destroy!:与destroy相同,但假如删去失利会抛出反常。

  5. destroy_all:删去契合条件的一切模型目标,不进行任何回谐和验证。

  6. destroy_by(conditions):依据条件删去契合条件的单个模型目标,不进行任何回谐和验证。

  7. save:将当时模型目标的特点值保存到数据库中。假如目标不存在,则创立一个新的目标。

  8. save!:与save相同,但假如保存失利会抛出反常。

  9. save(validate: false):与save相同,但不进行模型目标的验证。

  10. toggle!:将当时模型目标的布尔类型特点取反并保存到数据库中。

  11. touch:更新当时模型目标的updated_at字段,并保存到数据库中。这个办法一般用于更新缓存或触发回调办法。

  12. update_attribute(name, value):更新当时模型目标的单个特点值,并直接保存到数据库中,不进行任何验证。

  13. update(attributes):更新当时模型目标的特点值,并保存到数据库中。能够传入一个哈希表参数attributes表明要更新的特点值。

  14. update!(attributes):与update相同,但假如更新失利会抛出反常。

  15. valid?:检查当时模型目标是否经过验证。假如验证失利,能够运用errors办法检查错误信息。

这些办法是Rails中常用的Active Record模型操作办法,能够用于创立、更新、删去和验证模型目标。需求留意的是,这些办法中有些会触发回调办法、进行验证或抛出反常,详细运用时需求依据实际状况挑选适宜的办法。

扫描二维码推送至手机访问。

版权声明:本文由51Blog发布,如需转载请注明出处。

本文链接:https://www.51blog.vip/?id=206

标签: ruby on rails
分享给朋友:

“Callback详解” 的相关文章

delphi为什么没人用了,Delphi为何逐渐淡出开发者视野?

Delphi 是一种编程语言和集成开发环境(IDE),由 Borland(现在的 Embarcadero Technologies)开发,主要面向 Windows 平台。它在 1990 年代和 2000 年代初期非常流行,尤其是在桌面应用开发领域。随着时间的推移,Delphi 的使用逐渐减少,原因可...

c语言的三种基本结构,构建高效程序的基石

C语言的三种基本结构是顺序结构、选择结构和循环结构。1. 顺序结构:顺序结构是最基本的结构,它按照程序代码的先后顺序执行。在顺序结构中,程序从第一条语句开始执行,然后依次执行后续的语句,直到程序结束。2. 选择结构:选择结构用于根据不同的条件执行不同的语句。在C语言中,选择结构主要有两种形式:if语...

pascal教程,Pascal编程语言入门教程

1. 菜鸟教程:该教程适合想要学习Pascal编程语言的软件专业人员,介绍了Pascal的功能、数据类型、编程结构、面向对象等概念。你可以在这里了解Pascal的历史、应用、优势和与其他语言的关系,以及如何使用Pascal编写简单的程序。2. W3Cschool Pascal教程:这个教程提供了Pa...

java连接数据库

java连接数据库

Java连接数据库通常涉及以下几个步骤:1. 加载数据库驱动:首先需要加载数据库的驱动程序。这通常通过调用 `Class.forName` 方法完成。2. 建立数据库连接:使用 `DriverManager.getConnection` 方法来建立与数据库的连接。你需要提供数据库的URL、用户名和密...

php如何安装,从入门到环境搭建

php如何安装,从入门到环境搭建

安装PHP是一个多步骤的过程,通常取决于您正在使用的操作系统。以下是在不同操作系统上安装PHP的基本步骤: Windows1. 下载PHP: 访问下载PHP。 选择与您的Windows版本兼容的版本。2. 安装PHP: 双击下载的`.msi`文件启动安装程序。 按照提示完成安...

jav go,深入探讨Java与Go语言的差异与应用场景

jav go,深入探讨Java与Go语言的差异与应用场景

It seems like you're looking for information about the Java programming language. Java is a widelyused objectoriented programming language and computi...