让我们从一个简单的问题开始。
你在任何应用中见过
config.load_defaults 6?
6是一个说法,可能会有所不同,我只是举一个例子。
在将一个Rails应用程序从5.1升级到6.0时,我们有一个 "简单 "的问题。
我们应该运行rails app:update 命令吗?
快速的答案是:是的,我们应该,为什么不呢?
运行rails app:update 命令后,该命令为我们做了许多文件修改。
是时候运行测试套件了,你猜怎么着?所有的东西都失败了。 下一步是撤消所有的改动,从一个我们认为简单安全的配置改动开始。 然后我们添加了config.load_defaults 6.0 行,再次运行测试套件。 它仍然失败了。
为了仔细检查,我们把那一行注释回来,并运行了测试套件。 所有的东西都通过了,所以那行小字破坏了一切。
我们决定把重点放在config.load_defaults 6.0 。
我们在rails core中搜索了def load_defaults ,看看load_defaults 是做什么的。花点时间来理解它。
如果你无法导航到rails核心代码,我在下面添加了load_defaults 方法。
# rails/railties/lib/rails/application/configuration.rb
def load_defaults(target_version)
case target_version.to_s
when "5.0"
# rails 5.0 default configuration
when "5.1"
load_defaults "5.0"
# rails 5.1 default configuration
when "5.2"
load_defaults "5.1"
# rails 5.2 default configuration
when "6.0"
load_defaults "5.2"
# rails 6 default configuration
when "6.1"
load_defaults "6.0"
# rails 6.1 default configuration
when "7.0"
load_defaults "6.1"
# rails 7 default configuration
when "7.1"
load_defaults "7.0"
# rails 7.1 default configuration
else
raise "Unknown version #{target_version.to_s.inspect}"
end
@loaded_config_version = target_version
end
首先引起我注意的是,它以之前的rails版本为参数,递归地调用同一个load_defaults 方法。
def load_defaults(target_version)
case target_version.to_s
when "5.1"
load_defaults "5.0" # here
when "5.2"
load_defaults "5.1" # here
when "6.0"
load_defaults "5.2" # here
else
end
end
这意味着它将加载你指定的版本的默认配置,同时也会加载所有以前的版本作为回退。
例如:如果你在你的Rails应用程序中使用config.load_defaults("6.1") ,它将为版本6.0 、5.2 、5.1 和5.0 实现load_defaults 作为回退。
这很好,因为你不需要在自己的项目中添加所有这些配置行。
load_defaults 是做什么的?
简单地说,load_defaults 方法是加载从Rails 5开始到Rails 7.1的默认rails配置(因为它是目前最新的版本)。
那么,为什么我的应用程序会失败?
在审查了该应用程序后,我们注意到config.load_defaults 在以前的更新中被删除了,当我们把它加回来时,它出现了一个错误,因为当前版本的Rails的load_defaults 方法启用了config.belongs_to_required_by_default = true
将config.belongs_to_required_by_default 改为false ,就可以解决这个问题。
我们应该使用它吗?
这是一个很好的问题,快速的答案是也许!我们应该使用它。大笑。
较长的答案是:你以前是如何使用rails配置的?如果你一直在使用load_defaults 配置,那么在你的下一次更新中使用它似乎是安全的。
如果你没有使用过它,首先要确保阅读默认值部分的每一条规则,并仔细检查你的应用程序是否与所有这些规则兼容。