Callback详解

这篇具有很好参考价值的文章主要介绍了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 ||= "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模型操作方法,可以用于创建、更新、删除和验证模型对象。需要注意的是,这些方法中有些会触发回调方法、进行验证或抛出异常,具体使用时需要根据实际情况选择合适的方法。文章来源地址https://www.toymoban.com/news/detail-420195.html

到了这里,关于Callback详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Registration Authority 简介

    在公共密钥基础设施(PKI)中,CA(Certificate Authority,证书颁发机构)系统的RA(Registration Authority,注册机构)是PKI体系结构的重要组成部分。RA在CA系统中扮演着关键角色,负责处理用户的身份验证和注册请求,然后将这些请求传递给CA进行证书颁发。以下是关于RA的详细介绍

    2024年02月08日
    浏览(29)
  • [ruby on rails] passenger+nginx 部署rails

    安装Passenger 方法1 Passenger 是一个 app server,支持基于 Rack 框架的 Ruby app(包括 Rails),作为模块变异到Nginx,不需要自己启动。 安装 Passenger 最简单的方法是通过 apt 安装,首先导入 Passenger 的密钥(官方文档): 安装 apt 插件以支持 https 传输: 添加 apt 源(对应 Ubuntu 16.04

    2024年02月09日
    浏览(42)
  • PCL - 3D点云配准(registration)介绍

    前面多篇博客都提到过,要善于从官网去熟悉一样东西。API部分详细介绍见 Point Cloud Library (PCL): Module registration 这里博主主要借鉴Tutorial里内容(博主整体都有看完) Introduction — Point Cloud Library 0.0 documentation 接下来主要跑下Registration中的sample例子 一.直接运行下How to use iter

    2024年02月12日
    浏览(49)
  • 【Image Registration】图像配准综述

    图像配准 是将在 同一场景 下,但 不同时间点 ,或 不同视角 ,或 不同采集设备 拍摄的多幅(≥2)图像进行匹配。假设有两幅图像 Fixed Image 和 Moving Image ,图像配准就是要寻找一种空间变换( Transformation ),将 moving image 变换到 fixed image 上,使得两幅图中对应同一空间位

    2024年02月05日
    浏览(40)
  • Rails注释

    Rails视图页面和控制器的注释可以使用不同的方式进行添加 对于视图页面的注释,你可以在HTML或ERB标签内使用HTML注释,如下所示: 你还可以在ERB标签内使用Ruby注释,如下所示: 对于控制器的注释,你可以使用Ruby的单行注释或多行注释来添加,如下所示: 请注意,这些注释

    2024年02月16日
    浏览(47)
  • rails--访问项目首页

    访问项目首页 先在命令行中运行(记着在要访问项目的目录下eg:  /workspace/library ) bunlde exec rails server 然后打开浏览器 , 访问 localhost:3000 , 能看到首页 .( 这个页面是存在于 gem文件中的 . 在 library 目录下找不到它 )现在只有结构 .没有内容,所以需要增加内容 , 例如: 输入一个网

    2024年02月15日
    浏览(35)
  • rails--安装与启动

    安装 Rails ( 命令都在 Linux 端 .) 1. 安装了 ruby ,输入命令 ●  $ gem install bundler ● $ gem install rails -v 4.2.11.3 2 安装时会出现一系列的命令 , 最后输入  $ rails -v,   看到显示版本号 , 就安装好了 创建一个 Rails 项目 使用命令 : $ rails new 项目名 , 例如 : ● $ cd /workspace ● $ rails new

    2024年02月12日
    浏览(32)
  • Rails 中的布局和渲染

    在 Rails 中,视图是用于呈现 HTML、XML、JSON 等响应的模板。Rails 的视图系统支持模板、局部模板和布局模板,它们分别用于分离代码、提高代码重用性和提供统一的外观。 模板是视图的基本构建块。模板可以包含 HTML、Ruby 代码和其他标记,以生成动态内容。在 Rails 中,模板

    2023年04月24日
    浏览(36)
  • [ruby on rails] docker

    ubuntu14.04后自带docker安装包,可以直接安装 查看docker信息 docker命令 获取镜像 该命令实际上相当于 $ sudo docker pull registry.hub.docker.com/ubuntu:12.04 命令,即从注册服务器 registry.hub.docker.com 中的 ubuntu 仓库来下载标记为 12.04 的镜像。 有时候官方仓库注册服务器下载较慢,可以从其

    2024年02月09日
    浏览(38)
  • Gitlab升级报错二:rails_migration[gitlab-rails] (gitlab::database_migrations line 51)

    gitlab-ctl 修改文件目录后出现以下错误:从root -- home 先停掉gitlab: 单独启动数据库,如果不单独启动数据库,就会报以上错误 解决办法: 执行结束没有任何信息提示之后: 显示OK后, 重新加载配置: 最后重启gitlab:  

    2024年02月12日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包