2023 年 10 月 5 日,星期四

Rails 7.1:Dockerfiles、BYO 身份验证、更多异步查询等!

作者:rafaelfranca

Rails World 刚刚开始,我们正在与社区线下聚会,庆祝 Rails 诞生 20 周年和 Rails 7.1 的发布。

自 Rails 7.0 发布以来,此版本已由超过 800 名贡献者进行了超过五千次提交,因此它充满了新功能和改进。

用于新应用程序的 Dockerfiles

当您运行 rails new 时,Rails 现在将生成您使用 Kamal 或任何其他基于 Docker 的部署设置部署应用程序所需的所有 Dockerfiles。这些 Dockerfiles 为生产使用进行了调整,具有适当的缓存层、多阶段构建以最大限度地减小映像大小,以及无论您是否使用 JavaScript 构建环境都需要的所有依赖项。

构建您自己的身份验证改进

为了补充 has_secure_password,Rails 7.1 带来了帮助开发人员构建自己的身份验证系统的新功能。

首先,normalizes 声明属性规范化。这对于在将属性保存到数据库之前对其进行规范化很有用

class User < ApplicationRecord
  normalizes :email, with: -> email { email.strip.downcase }
end

user = User.create(email: " [email protected]\n")
user.email                  # => "[email protected]"

其次,authenticate_by 在控制器中验证用户时,可防止常见的计时攻击

User.authenticate_by(email: "[email protected]", password: "railsrocks")

第三,generates_token_for 可用于实现诸如密码重置、电子邮件确认以及其他需要一次性令牌的功能

class User < ApplicationRecord
  has_secure_password

  generates_token_for :password_reset, expires_in: 15.minutes do
    # Last 10 characters of password salt, which changes when password is updated:
    password_salt&.last(10)
  end
end

user = User.first

token = user.generate_token_for(:password_reset)
User.find_by_token_for(:password_reset, token) # => user
# 16 minutes later...
User.find_by_token_for(:password_reset, token) # => nil

最后,has_secure_password 现在可以自动在更新密码时验证当前密码。这对于检查尝试更新密码的用户是否知道当前密码很有用

# Schema: User(name:string, password_digest:string)
class User < ActiveRecord::Base
  has_secure_password
end

user = User.new(name: "rafael", password: "railsrocks", password_confirmation: "railsrocks")
user.save                                                                      # => true
user.update(password: "pwn3d", password_challenge: "")                         # => false, challenge doesn't authenticate
user.update(password: "railsGetsEvenBetter", password_challenge: "railsrocks") # => true

更多 Active Record 异步查询

Active Record 中的异步查询支持 已得到极大扩展。这使得并行运行多个缓慢的查询变得更加容易,尤其是那些专注于计算的查询,同时允许请求处理继续进行。存在用于异步聚合的新方法(例如 countsum 等)、返回单个记录的方法,以及除 Relation 之外的任何内容

  • async_count
  • async_sum
  • async_minimum
  • async_maximum
  • async_average
  • async_pluck
  • async_pick
  • async_ids
  • async_find_by_sql
  • async_count_by_sql

对 Trilogy MySQL 适配器的内置支持

Trilogy 是 GitHub 为 Rails 创建的新 MySQL 数据库适配器,旨在提高性能、灵活性和嵌入的易用性,超过了现有的 mysql2 选项。它在 GitHub 和 Shopify 上运行,现在在 Rails 中作为选项开箱即用。从 Rails 的下一个主要版本开始,它很可能成为新的默认选项。

支持 Active Record 中的复合主键

Shopify 通过切换到复合主键,将对他们最大表的常见查询的性能提高了 5-6 倍,并将慢速查询的数量减少了 80%。权衡是插入操作可能会变得明显更慢,但对于读取次数远大于写入次数的非常大的表,这可能是一个巨大的改进。这项工作已被提取到对 Active Record 中复合主键的完全支持中。

使用 perform_all_later 排队大量作业

Active Job 中的perform_all_later 方法 已被添加以简化同时排队大量作业的过程。此强大的补充功能允许您有效地排队作业,而不会触发回调。当您需要一次排队一批作业时,这特别有用,减少了对队列数据存储的多次往返的开销。

介绍 config.autoload_libconfig.autoload_lib_once 以增强自动加载

已引入一种新的配置方法 config.autoload_lib(ignore:)。此方法用于通过包含 lib 目录来增强应用程序的自动加载路径,该目录默认情况下不包含。此外,config.autoload_lib(ignore: %w(assets tasks)) 是为新应用程序生成的。(此功能不适用于引擎。)

支持 Bun

您现在可以使用 Bun 作为您的 JavaScript 运行时来生成新应用程序。为此,您可以将 --javascript=bun 选项传递给 rails new

庆祝此版本并展望下一个版本

Rails 7.1 已发布,但我们已经在考虑下一个版本。我们将在 Rails World 上分享一些想法,我们将与社区线下互动,讨论想法并收集一些反馈。

我们期待下一个版本,希望您也是!