试用Rails6新增的小功能之一:112(database.yml警告部分)

首先

在第112段中试用Rails 6中的新增功能。这次我们讲解的是database.yml警告部分。
在Rails 6中,可以支持多个数据库,但是如果在database.yml文件中使用复杂的ERB语法,就会发出警告。

我已经确认了Ruby 2.6.5和Rails 6.0.1。(似乎在Rails 6.0.0中已经进行了修复。)

$ rails --version
Rails 6.0.1

为了发出警告,这次我想尝试通过环境变量DB来切换访问MySQL数据库或PostgreSQL数据库。
不使用多个数据库功能。

创建一个Rails项目

$ rails new rails_sandbox
$ cd rails_sandbox

在Gemfile中添加mysql2和pg。

为了能够连接到MySQL和PostgreSQL,需要在Gemfile中添加mysql2和pg。

gem 'pg', '>= 0.18', '< 2.0'
gem 'mysql2'

执行 bundle install。

$ bundle install

请编辑database.yml文件。

修改database.yml文件.

添加MySQL的连接设置和PostgreSQL的连接设置。

通过环境变量,可以实现切换连接的功能。

在这里,关键是`<%= ENV.fetch(“DB”) { ‘postgresql’ } %>`这部分。
这个描述将导致警告出现。

mysql: &mysql
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  host: db_mysql

postgresql: &postgresql
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  host: db_postgresql
  user: <%= ENV.fetch("POSTGRES_USER") %>
  password: <%= ENV.fetch("POSTGRES_PASSWORD") %>

development:
  <<: *<%= ENV.fetch("DB") { 'postgresql' } %>
  database: app_development
  ...

test:
  <<: *<%= ENV.fetch("DB") { 'postgresql' } %>
  database: app_test
  ...

production:
  <<: *<%= ENV.fetch("DB") { 'postgresql' } %>
  database: app_production
  ...

创建脚本

只是为了确认,我会写一个脚本来解析database.yml文件并输出结果。

yml = ERB.new(File.read(Rails.root.join('config/database.yml')))
print yml.result

运行脚本

执行脚本,没有出现任何错误并成功解析。

请注意下一行的开发代码: <<: *postgresql 的处理流程。

$ bin/rails runner scripts/parse_database_yml.rb
Running via Spring preloader in process 104
mysql: &mysql
  adapter: mysql2
  ...

postgresql: &postgresql
  adapter: postgresql
  ...

development:
  <<: *postgresql
  database: app_development
  ...

执行db:create

执行db:create。
Rails无法推断你是否在使用多个数据库,从你的database.yml中…请简化你的ERB。警告。

$ bin/rails db:create
Rails couldn't infer whether you are using multiple databases from your database.yml and can't generate the tasks for the non-primary databases. If you'd like to use this feature, please simplify your ERB.
Created database 'app_development'
Created database 'app_test'

为什么会发出警告

为了支持多个数据库,Rails在启动之前读取database.yml文件并生成任务。在生成任务时,它不使用ERB而是使用DummyCompiler进行解析,并且据说DummyCompiler会在无法处理的情况下发出警告。

我该怎么办才好?

只要修改 ERB 部分,使其没有警告,那就可以了。然而,对于通常应该如何修改,笔者也不太清楚。

为了避免警告,进行修复。

通过修改如下,我们可以避免警告:
我们使用 if 语句添加了 default,并切换了使用开发环境等,这样修正后,我们不再使用 *default 来使用 ERB。

mysql: &mysql
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  host: db_mysql

postgresql: &postgresql
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  host: db_postgresql
  user: <%= ENV.fetch("POSTGRES_USER") %>
  password: <%= ENV.fetch("POSTGRES_PASSWORD") %>

default: &default
  <% database = ENV.fetch("DB"){ 'postgresql' } %>
  <% if database == 'postgresql' %>
  <<: *postgresql
  <% else %>
  <<: *mysql
  <% end %>

development:
  <<: *default
  database: app_development
  ...

test:
  <<: *default
  database: app_test
  ...

production:
  <<: *default
  database: app_production
  ...

嘗試過的醬料 de

试验用的源码位于以下位置:
https://github.com/suketa/rails_sandbox/tree/try112_warn_database_yml – 存在警告的版本
https://github.com/suketa/rails_sandbox/tree/try112_warn_database_yml_fix – 已修复警告的版本

参考资料

    • Warn if we can’t read the yaml to create database tasks

 

    Load YAML for rake tasks without parsing ERB
广告
将在 10 秒后关闭
bannerAds