时隔一年半,期待已久的 Rails 6.1 终于发布了。趁着双休,给 GeekWeibo 从 Rails6.0 升级到了 6.1。 升级主要有三步。
为了避免一些 gem 版本的不兼容,我先本地gem install rails
把系统的 rails 版本升级到 6.1。然后使用 rails new demo61
创建了一个新 app 叫 demo61。接着对比 demo61/Gemfile 和 geekweibo/Gemfile 里面各个 gem 的版本号,相应的升级一下版本号。主要 diff 如下:
然后执行 bundle update
。
前几天才知道原来还有 rails app:update
这个命令,用于 app 升级。执行一下,按照提示,相应的覆盖或忽略一些文件更新。执行完了之后,很多 bin 文件和 config 文件都更新了。同时会生成两个新的 active_storage 的 migration file。一个是给 active_storage_blobs
table 新增了一个 service_name
column:
# This migration comes from active_storage (originally 20190112182829)
class AddServiceNameToActiveStorageBlobs < ActiveRecord::Migration[6.0]
def up
unless column_exists?(:active_storage_blobs, :service_name)
add_column :active_storage_blobs, :service_name, :string
if configured_service = ActiveStorage::Blob.service.name
ActiveStorage::Blob.unscoped.update_all(service_name: configured_service)
end
change_column :active_storage_blobs, :service_name, :string, null: false
end
end
def down
remove_column :active_storage_blobs, :service_name
end
end
另外一个是新增了一个active_storage_variant_records
table
# This migration comes from active_storage (originally 20191206030411)
class CreateActiveStorageVariantRecords < ActiveRecord::Migration[6.0]
def change
create_table :active_storage_variant_records do |t|
t.belongs_to :blob, null: false, index: false, type: :uuid
t.string :variation_digest, null: false
t.index %i[ blob_id variation_digest ], name: "index_active_storage_variant_records_uniqueness", unique: true
t.foreign_key :active_storage_blobs, column: :blob_id
end
end
end
接着执行 rails db:migrate
,一切正常。
我的项目是使用 capistrano 来部署的。执行完前面的两个步骤,本地试运行,解决掉一个 gem 的兼容性问题(后面会提到)之后。执行cap production deploy
之后,提示没有 cap production puma:restart
这个 task。一番 google 之后,发现原来是 puma 5 把 daemon 启动模式去掉了。相应的 capistrano3-puma 5.0 之后的版本,默认的 task 里面也自然没有这个启动模式了。
解决办法是使用systemd、monit、pm2这些第三方的 process monitor/manager。我因为不想折腾,所以采用linux(或者说ubuntu)自带的systemd。
在 Capfile 里面新增一行
# 在install_plugin Capistrano::Puma 之后
install_plugin Capistrano::Puma::Systemd
然后执行
cap puma:systemd:config # 会生成一个systemd unit文件,并上传到服务器的/etc/systemd/system/文件夹下面。
cap puma:systemd:enable # Enable上一步上传的service
然后再执行 cap production puma:restart
,这个命令会在服务器上面会执行sudo systemctl restart puma
这时候提示报错了,说 systemd 的 service unit 里面,ExecStart 的命令格式有问题。我查看了一下,发现生成的 unit 文件里面,ExecStart 这一行的内容是
ExecStart=~/.rvm/bin/rvm default do bundle exec puma -C /your/deploy/path/geekweibo/shared/puma.rb
我猜测是~/
这个地方出错了。改成绝对路径
ExecStart=/home/username/.rvm/bin/rvm default do bundle exec puma -C /your/deploy/path/geekweibo/shared/puma.rb
然后在服务器上面执行 sudo systemctl daemon-reload
,因为我们修改了 unit 文件,需要 reload 一下 systemd daemon 生效。
回到开发机,再次执行cap production puma:restart
,果然就可以了。我猜测之所以 ~/
这种写法会有问题,是因为我没有指定 puma 的 user。
不少朋友说升级 6.1 之后,遇到很多 gem 不兼容的情况。可能是因为我这个项目比较小,我这次升级,只遇到一个 gem 不兼容。那就是skylight-ruby gem(一个 APM 服务)。报了一个
NoMethodError (undefined method `instrument' for #<ActionView::TemplateRenderer:0x00007f9d9cc61ee8>)
这样的错。这个 gem 的Github issues里面也有不少人反映这个问题。据作者说,gem 新版 beta 里面已经解决了,不过我不想采坑,所以没上 beta,只是按照他们的说明,用了一个 workaround,在 config/application.rb 里面加一行
config.skylight.probes -= %w[action_view]
解决了问题。
好像没发现。Rails 6.1 很多新增功能是针对 multiple DB 的,对我好像没什么影响。我主要是冲着 strict loading 和 activestorage 的 permanent url 来的。其中 strict loading,在另外的一个小 app 里面开了 strict loading by default,结果带来一些问题,于是又禁用了。而 activestorage 的 permanent url,除了方法名使用 url
代替 service_url
,其他好像也没发现什么区别。我原来使用 service_url
获取到的 url,貌似也不会变?不清楚是不是我理解还不到位。
总体来说,因为项目比较小,这次升级还是比较顺利的,但好像也没带来什么特别的优势。所以,对于想升级的朋友,可以参考一下。