趣味で動かしているRails6.0.x、Ruby 2.7.1のアプリ3つをRails 6.1、Ruby 3.0.0(rc1)にまで上げようと試みた。 そのときに遭遇した問題をまとめたもの。
ひとまずRails 6.1、Ruby 2.7.2まで上げることにした。 以下、その過程で踏んだ問題。
rails aborted! LoadError: cannot load such file -- listen
rails app:update
を叩いたときに出てきた。
gem 'listen'
を追加。
Rails 6.1はActiveStorage周りのスキーマも変わっていて、 rails app:update
を実行するとマイグレーションファイルが追加されるので実行をお忘れなく。
NoMethodError: undefined method `parent' for MyApplication::Application:Class
rails db:migrate
を実行したときにrails-erdで出る。
Rails 6.1 support · Issue #363 · voormedia/rails-erd · GitHub の通り、issueは立っているが作者が1年ぐらい更新してないので更新されるか望み薄。
とりあえずフォーク版で修正してくれていたのでそれを使うようにした。
gem 'rails-erd', github: 'guapolo/rails-erd'
uninitialized constant NestedForm::BuilderMixin (NameError)
同じく rails db:migrate
の時に発生。rails_admin
の問題の様子。
config/initializers/rails_admin.rb
に2行のrequireを追加した。
refs: uninitialized constant NestedForm::BuilderMixin · Issue #887 · sferik/rails_admin · GitHub
require "nested_form/engine" require "nested_form/builder_mixin"
NoMethodError: undefined method `assert_nothing_raised'
RSpecのSystemSpecで出るようになっていた。
rspec - Rails 6.1 upgrade: undefined method `assert_nothing_raised' - Stack Overflow
これと同じ問題だったのでspec/rails_helper.rb
に以下を追加
config.include ActiveSupport::Testing::Assertions
SystemStackError - stack level too deep
developmentで試しに動作確認しようとしたら出た。
stacktrace的に meta_request
というGemが怪しかったので試しにオフにしたら解決。
特に使っていなかったのでそのまま削除。
activesupport (6.1.0) lib/active_support/core_ext/object/json.rb:174:in `block in as_json' activesupport (6.1.0) lib/active_support/core_ext/object/json.rb:173:in `each' activesupport (6.1.0) lib/active_support/core_ext/object/json.rb:173:in `as_json' activesupport (6.1.0) lib/active_support/core_ext/object/json.rb:57:in `as_json' activesupport (6.1.0) lib/active_support/core_ext/object/json.rb:174:in `block in as_json' activesupport (6.1.0) lib/active_support/core_ext/object/json.rb:173:in `each' activesupport (6.1.0) lib/active_support/core_ext/object/json.rb:173:in `as_json' activesupport (6.1.0) lib/active_support/core_ext/object/json.rb:174:in `block in as_json' activesupport (6.1.0) lib/active_support/core_ext/object/json.rb:173:in `each' activesupport (6.1.0) lib/active_support/core_ext/object/json.rb:173:in `as_json' activesupport (6.1.0) lib/active_support/core_ext/object/json.rb:57:in `as_json' activesupport (6.1.0) lib/active_support/json/encoding.rb:35:in `encode' activesupport (6.1.0) lib/active_support/json/encoding.rb:22:in `encode' activesupport (6.1.0) lib/active_support/core_ext/object/json.rb:42:in `to_json' meta_request (0.7.2) lib/meta_request/event.rb:46:in `block in json_encodable' meta_request (0.7.2) lib/meta_request/event.rb:66:in `block in transform_hash' meta_request (0.7.2) lib/meta_request/event.rb:60:in `each' meta_request (0.7.2) lib/meta_request/event.rb:60:in `inject' meta_request (0.7.2) lib/meta_request/event.rb:60:in `transform_hash' meta_request (0.7.2) lib/meta_request/event.rb:38:in `json_encodable' meta_request (0.7.2) lib/meta_request/event.rb:15:in `initialize' meta_request (0.7.2) lib/meta_request/app_notifications.rb:69:in `new' meta_request (0.7.2) lib/meta_request/app_notifications.rb:69:in `block in subscribe' meta_request (0.7.2) lib/meta_request/app_notifications.rb:81:in `block in subscribe'
NameError: uninitialized constant ActiveJob::Logging::LogSubscriber
ActiveJobの引数に巨大な値を指定するとログが一瞬で埋まるのでsnipするために挟んでいた。 6.0.xから6.1でこの辺が変わっていたみたい。
diff --git a/config/initializers/active_job_custom_logger.rb b/config/initializers/active_job_custom_logger.rb index 1b352a6..856338a 100644 --- a/config/initializers/active_job_custom_logger.rb +++ b/config/initializers/active_job_custom_logger.rb @@ -1,4 +1,4 @@ -require 'active_job/logging' +require 'active_job/log_subscriber' module ActiveJobCustomLogger def args_info(job) @@ -9,4 +9,4 @@ module ActiveJobCustomLogger end end -ActiveJob::Logging::LogSubscriber.prepend(ActiveJobCustomLogger) +ActiveJob::LogSubscriber.prepend(ActiveJobCustomLogger)
ArgumentError: You tried to define an enum named "bar_status" on the model "Hoge", but this will generate a instance method "_?", which is already defined by another enum.
enum値に日本語を使ってると(正確には英数字以外を使っていると)正規表現で消されてしまって重複メソッド扱いになりエラーとなる。 https://github.com/rails/rails/blob/v6.1.0/activerecord/lib/active_record/enum.rb#L205
一応issueにコメントだけしたけど、コーナーケースすぎるのでそもそもコメントしようか悩んだ…。 背景的にはローカライズが必要ない(する予定がない)のでそのまま日本語を入れていた。
https://github.com/rails/rails/issues/40804#issuecomment-751440989
2021/01/09追記
kamipoさんが6.1.1で直してくれた。感謝。
manifest unknown
Ruby, Railsと直接関係ないポカミス。 masterにマージしてimageを作る際に出た。
ruby:2.7.2-alpine3.10
なんてイメージはないので ruby:2.7.2-alpine3.12
に修正。
Step 1/22 : FROM ruby:2.7.2-alpine3.10 manifest for ruby:2.7.2-alpine3.10 not found: manifest unknown: manifest unknown
rails aborted! LoadError: Error loading shared library liblzma.so.5: No such file or directory (needed by /usr/local/bundle/gems/nokogiri-1.10.10/lib/nokogiri/nokogiri.so) - /usr/local/bundle/gems/nokogiri-1.10.10/lib/nokogiri/nokogiri.so
Rails 6.1、Ruby 2.7.2の段階で一回デプロイしておいた。 趣味なので多少エラーが出ても良いし、Ruby 3に関係ないところで問題があるなら切り分けて確認しておきたいため。
どこかで見たことがあるエラー、 prod環境の rails db:migrate
時に発生。
alpineだとありがちなイメージがあったのでこの機会にslim-busterに移行した。
イメージサイズが135MB->285MBになってしまった…。 とはいえ特に問題なく普通に動くのがコンテナのいいところ。
Ruby 3化
バージョン管理にasdfを使っているが、3.0.0が選べなかったので調べてたらここに行き着いた。
Increment ruby-build for Ruby 3.0.0 support by f440 · Pull Request #192 · asdf-vm/asdf-ruby · GitHub
ASDF_RUBY_BUILD_VERSION=v20201225 asdf install ruby 3.0.0
でインストール。
まず起動しようとするとcannot load such file -- webrick/httputils (LoadError)
が出た。
全く心当たりが無いのでstacktraceを見ると、
/vendor/bundle/ruby/3.0.0/gems/mechanize-2.7.6/lib/mechanize.rb:12:in `<main>
太古に使ってたGemなので削除。
次に cannot load such file -- binding_of_caller.bundle (LoadError)
が出た。
stacktraceを見ると、
/vendor/bundle/ruby/3.0.0/gems/binding_of_caller-0.8.0/lib/binding_of_caller.rb:9:in `<main>'
BetterErrorsを使うために入れていたけど、試しに消してみる。 Gemfile.lockを見ると、
pry-stack_explorer (0.5.1) binding_of_caller (~> 0.7)
の依存でまだ残っていたのでpry-stack_explorerも消す。 これでようやくrails sで起動するようになった。
最近はirbも進化してるし、productionではpryを使ってないのでirbに移行しよう。 BetterErrorsも便利だったけどweb-consoleで十分かな。という断捨離の気持ちが得られた。 Rails触りはじめの頃に使ったアプリなので不要なgemがたくさん入ってしまっている…。
web-consoleはVimiumと干渉してまともにタイプできないことが一番きつい。 jsで入力キーを取得してpreタグの中で入れ込むような挙動になっているようなので、素直にinputタグにしてくれたら大丈夫そうだけど、色々フックされてるっぽいのでややこしそう…。 あるいは一時的にVimiumをオフにするショートカットキーなどがあればそれで対応する形になるか…。
Ruby公式もテスト用の circleci/ruby
もRC版しかなかったので一旦RC1のイメージを使うようにした。
ruby:3.0.0-rc1-slim-busterにはgitが入っていなかったので、gitをapt-get installに追加。 この状態でデプロイして特に問題なく動作したので、あとは正式版のイメージが出たら切り替えようかな、というぐらい。 ちょくちょく動かないものがあって断捨離をしたけど、結果的に良かった気がする。
全体の所感としては依存が多くなるほどアップデートのときに大変で運用コストがかかるので極力依存を増やさずにものを作ろうという気持ちに改めてなった。
あと複数アプリで更新作業をしてると rails app:update
の実行で config/environments
の差分をちゃんと反映する作業が一番精神的に大変だった。
カスタム設定は末尾に記載してなるべく差分反映の影響を受けないところに置いておくのがいいのかもしれない。