Help us learn about your current experience with the documentation. Take the survey.
Rails 初始化器
初始化器在 Rails 进程启动时执行。这意味着每次部署时也会执行初始化器。
默认情况下,Rails 会在 config/initializers 中的初始化器加载后加载 Zeitwerk。
在 Zeitwerk 加载前进行自动加载现已弃用,但由于我们在初始化器中使用了大量自动加载的
常量,我们必须将 Zeitwerk 的加载提前到这些初始化器之前。
这样做的一个副作用是,在初始化器中,config.autoload_paths 已经被冻结。
要在 Zeitwerk 加载前运行初始化器,需要将它们放在 config/initializers_before_autoloader 中。
该文件夹中的 Ruby 文件按字母顺序加载,就像默认的 Rails 初始化器一样。
需要这样做的示例包括:
- 修改 Rails 的
config.autoload_paths - 更改 Zeitwerk 使用的配置,例如词形变化
初始化器中的数据库连接
理想情况下,不应从 Rails 初始化器中打开数据库连接。从初始化器中打开
数据库连接(例如,检查数据库是否存在,或执行数据库查询)意味着像 db:drop 和
db:test:prepare 这样的任务会失败,因为活动会话会阻止数据库被删除。
为防止这种情况,我们在路由加载期间阻止数据库连接的打开。这样做会导致错误:
RuntimeError:
初始化器期间不应调用数据库连接。
# ./config/initializers/00_connection_logger.rb:15:in `new_client'
# ./lib/gitlab/database/load_balancing/load_balancer.rb:112:in `block in read_write'
# ./lib/gitlab/database/load_balancing/load_balancer.rb:184:in `retry_with_backoff'
# ./lib/gitlab/database/load_balancing/load_balancer.rb:111:in `read_write'
# ./lib/gitlab/database/load_balancing/connection_proxy.rb:119:in `write_using_load_balancer'
# ./lib/gitlab/database/load_balancing/connection_proxy.rb:89:in `method_missing'
# ./config/routes.rb:10:in `block in <main>'
# ./config/routes.rb:9:in `<main>'