Rails 初始化器
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 这样的任务将失败,因为活动会话会阻止数据库被删除。
为了强制执行这一点:
- 我们运行 clear_active_connections_again 初始化器,以确保初始化后没有数据库连接保持活动状态。
- 我们不允许在路由中进行数据库查询。初始化器应该是静态且快速的;发出查询会减慢启动时间,并可能导致微妙的故障。
如果在加载路由时进行了数据库查询,则会向 STDOUT 打印一条警告,其中包含查询和回溯,例如:
shell1初始化器连接查询:SELECT "projects".* FROM "projects" WHERE "projects"."id" = 1 LIMIT 1 2初始化器连接回溯:config/routes.rb:15:in `block (2 levels) in <main>' 3初始化器连接回溯:config/routes.rb:9:in `block in <main>' 4初始化器连接回溯:lib/initializer_connections.rb:18:in `warn_if_database_connection' 5初始化器连接回溯:config/routes.rb:6:in `<main>' 6请参阅 https://gitlab.cn/docs/development/rails_initializers/#database-connections-in-initializers