こんにちは、hachi8833です。オレオレRailsアプリを5.1.3から5.2.1に、Rubyを最新の2.5.3にアップグレードしました。
環境
- macOS: Mojave
- Homebrewでrbenvをインストール
- ただしruby-buildは
~/.rbenv/plugins/ruby-build
にgit clone
で取得している
- ただしruby-buildは
- rbenvでRuby環境を構築している
- bundlerを使ってプロジェクトディレクトリの
vendor/
ディレクトリにgemを置いている - デプロイ先: Heroku(ステージングと本番)
1. Rubyのアップグレード
まずはRubyのアップグレードから。2.5.0を最新の2.5.3にアップグレードします。
cd ~/.rbenv/plugins/ruby-build
git pull
rbenv install 2.5.3
次はRailsのRubyを2.5.3にアップグレードします。
- Gemfileを更新します。
# Gemfile
-ruby '2.5.0'
+ruby '2.5.3'
- 以下を実行してvendorディレクトリのgemを更新します。
bundle install
bundle exec rails s
で動作を確認します。オレオレアプリは動的なページが1つしかないのでテストを回す意味がほぼありませんが、皆さんは必ずテストを回してください。
Herokuのステージングにデプロイして動作を確認できました。
git push enno-hachi-stg master
Railsのアップグレード
Rails アップグレードガイドの更新情報をみっちり読んでおきます。オレオレアプリに影響するところはなさそうでした。
- Gemfileを更新します。
# Gemfile
-gem 'rails', '5.1.3'
+gem 'rails', '5.2.1'
アップグレードガイドに従い、bundle exec rails app:update
を実行します。
何もなければこれでおしまいです。いつもはだいたいこんなものです。
参考: Rails アップグレードガイド | Rails ガイド
Railsアップグレードのトラブルシューティング
しかしこんな恥ずかしいほどちっぽけなRailsアプリですら、今回はエラーメッセージが表示されます。
$ bundle exec rails app:update
Fetching gem metadata from https://rubygems.org/..........
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies....
Bundler could not find compatible versions for gem "activemodel":
In snapshot (Gemfile.lock):
activemodel (= 5.1.3)
In Gemfile:
kaminari was resolved to 1.0.1, which depends on
kaminari-activerecord (= 1.0.1) was resolved to 1.0.1, which depends on
activerecord was resolved to 5.1.3, which depends on
activemodel (= 5.1.3)
rails (= 5.2.1) was resolved to 5.2.1, which depends on
activemodel (= 5.2.1)
Running `bundle update` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.
まずはkaminariを単独でアップデートします。bundle update kaminari
を実行します。
しかしメッセージはまったく同じでした。
そこでちょっと考えてからbundle update
を試してみました。ただしgem名を指定しないbundle update
は諸刃の剣。アップデートしてはまずいgemも含め全部を一気にアップデートするので、逆に事態をこじらせてしまう可能性もあります(↓以下の記事を参照)。オレオレアプリだからできることなので、業務アプリではこんな雑なことは絶対しないようにしましょう。
ちょっと待った! Railsでgitリポジトリから除外すべきでないファイル:Gemfile.lockとdb/schema.rb
どきどきしながらbundle update
し、bundle exec rails s
してみると、上のメッセージは解消しました。
factory_girlをfactory_botに変更
今度は以下です。ご存知のとおりfactory_girlはfactory_botに名前が変わったのですが、オレオレアプリではまだfactory_girlのままでした。
DEPRECATION WARNING: The factory_girl gem is deprecated. Please upgrade to factory_bot. See https://github.com/thoughtbot/factory_bot/blob/v4.9.0/UPGRADE_FROM_FACTORY_GIRL.md for further instructions. (called from require at /Users/hachi8833/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/bundler-1.16.6/lib/bundler/runtime.rb:81)
factory_girlをfactory_botに変更して再度bundle update
します(使ってないのでいっそ外してもいいくらいですが)。
案の定factory_girlがちょっぴりspecに残っていたのでfactory_botに更新しました。
FactoryBot.define do
factory :mypattern, class: Pattern do
regex 'ありがとうございません'
# ruby_block {}
comment '名作'
posi_sample 'ありがとうございません'
nega_sample 'ありがとうございます'
# hit_count
display_name '感謝'
comment_e 'Fuck you very much'
memorandom '世界遺産にしたい'
end
end
私の場合あまり意味はないのですが、変更/削除に伴いbundle exec rspec
を実行するとそこそこエラーが出ました。spec_helper.rbも修正が必要でした。
# spec_helper.rb
...
config.before :all do
FactoryGirl.reload # FactoryBotに変更する
end
config.include FactoryGirl::Syntax::Methods # FactoryBotに変更する
# 以下のDatabaseCleaner関連は削除する
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, js: true) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
system('bundle exec rake db:seed')
# my config
config.include AuthHelper
end
bundle exec rspec
すると今度は以下が出ました。factory_botの書式が変わったようです。このあたりは今度まとめて対応することにしました。
DEPRECATION WARNING: Static attributes will be removed in FactoryBot 5.0. Please use dynamic
attributes instead by wrapping the attribute value in a block:
【翻訳】factory_bot 4.11で非推奨になった静的属性(static attributes) - Qiita
不要なgemを削除
今度はrails_best_practicesが駄々をこねました。
/Users/hachi8833/deve/rails/enno/enno_master/vendor/bundle/ruby/2.5.0/gems/require_all-2.0.0/lib/require_all.rb:102:in `rescue in block in require_all': Could not require /Users/hachi8833/deve/rails/enno/enno_master/vendor/bundle/ruby/2.5.0/gems/rails_best_practices-1.18.1/lib/rails_best_practices/core/controllers.rb (uninitialized constant RailsBestPractices::Core::Klasses). Please require the necessary files (RequireAll::LoadError)
私の場合rails_best_practicesを直す意味がなかったので、この機会にgemを見直すことにしました。
- 使ってないので削除
- rails_best_practices
- sdoc
- derailed_benchmarks
- yard
- listen
- Rails 5に同じ機能があるので削除
- awesome_print
- launchy
- database_cleaner
- capybara-screenshot
gem見直しの際は以下を参考にしました。
Webサーバーを修正
さらに、development/testのWebサーバーがPumaなのに、productionがunicornだということに今頃気づいたのでPumaに統一しました。環境ごとにWebサーバーを変える意味まったくなし、お恥ずかしい。
+gem 'puma'
...
group :production do
- gem 'unicorn'
gem 'rails_12factor', '0.0.3' #Just for Heroku
gem 'google-analytics-rails'
end
JavaScript/CSSの応急処置
Gemfileのgemを削除/更新してからbundle update
後、bundle exec rails s
すると起動しました。以下のwarningが出ました。
autoprefixer: /Users/hachi8833/deve/rails/enno/enno_master/app/assets/stylesheets/introjs.css:11:3: Gradient has outdated direction syntax. Replace `cover` to `farthest-corner`.
仰せのとおりにintrojs.cssのcover
をfarthest-corner
に変更しました。サードパーティのファイルを直接変更するなど普通ならしませんが、を全然使ってないのでまたの機会に削除することにしました。
background: -moz-radial-gradient(center,ellipse farthest-corner,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%);
background: -webkit-gradient(radial,center center,0px,center center,100%,color-stop(0%,rgba(0,0,0,0.4)),color-stop(100%,rgba(0,0,0,0.9)));
background: -webkit-radial-gradient(center,ellipse farthest-corner,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%);
background: -o-radial-gradient(center,ellipse farthest-corner,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%);
background: -ms-radial-gradient(center,ellipse farthest-corner,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%);
background: radial-gradient(center,ellipse farthest-corner,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%);
再度bundle exec rails s
でローカルで実行できるかどうか確認しました。
# bundle exec rails s
=> Booting Puma
=> Rails 5.2.1 application starting in development
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.0 (ruby 2.5.3-p105), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop
これで一応めでたしです。
bootstrap-sassはまだsass-railsに依存している
しかしさっきupdate:app
したときに以下のメッセージが出ていました。
Ruby Sass is deprecated and will be unmaintained as of 26 March 2019.
* If you use Sass as a command-line tool, we recommend using Dart Sass, the new
primary implementation: https://sass-lang.com/install
* If you use Sass as a plug-in for a Ruby web framework, we recommend using the
sassc gem: https://github.com/sass/sassc-ruby#readme
* For more details, please refer to the Sass blog:
- gem 'sass-rails'
+ gem 'sassc'
しかし今度は以下のエラーです。
/Users/hachi8833/deve/rails/enno/enno_master/vendor/bundle/ruby/2.5.0/gems/bootstrap-sass-2.3.2.2/lib/bootstrap-sass.rb:14:in `require': cannot load such file -- sass-rails (LoadError)
enno_masterdevelopement8⬆1✔1✎ERROR$
bootstrap-sassのバージョンロックがいけないのかと思い、外してbundle update
しました。
-gem 'bootstrap-sass', '2.3.2.2'
-gem 'bootstrap-sass'
しかしうまくいきません。そもそもbootstrap-sassのgemspecにはsass-railsが指定されているので無理もありません。
bootstrap-sassはBootstrap 3向けですが、後発のBootstrap 4向け公式gemであるbootstrap-rubygemのgemspecをチェックすると、ちゃんとsasscが使われていました。使うならやはりこっちですね。
Bootstrap 4へのアップグレードはまたの機会とすることにします。
Herokuでのトラブル
しかしHerokuでstagingにデプロイすると、思いきりアプリケーションエラーになりました。さっきRubyのみをアップデートした時点では起きなかったのに...
どうやら以下のデプロイメッセージが原因のようです。
remote: ! Warning: You are running on a deprecated stack.
remote: ! Please upgrade to the latest stack by following the instructions on:
remote: ! https://devcenter.heroku.com/articles/upgrading-to-the-latest-stack
Upgrading to the Latest Stack | Heroku Dev Centerを参照すると、以下の実行が必要なようです。
$ heroku stack:set heroku-18 -a <app name>
heroku-18って何?と思ったら以下の記事にありました。今は16ではなく18なんですね。
参考: Herokuの新しいスタック「Heroku-16」で何が変わったか? (2017年5月8日よりデフォルトに) - Qiita
$ heroku stack:set heroku-16 -a enno-hachi-stg
なお、Herokuのスタックはデプロイするまでは前のスタックが使われ続けます。
Webサーバーの変更: 続き
ここでherokuのダッシュボードを見ると、web
となっているじゃありませんか。これをPumaに変えないとあかんようです。
bundle exec unicorn -p $PORT -c ./config/unicorn.rb
Heroku側で変えるのかと思いきや、Railsプロジェクト直下のProcfileを書き換える必要がありました。
- web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
+ web: bundle exec puma -C config/puma.rb
これでDynoの起動コマンドも更新されました。
これで無事stagingで動きました!
後は本番デプロイです。以下を忘れず実行してスタックを更新してから、git push heroku master
を実行します。
$ heroku stack:set heroku-16 -a enno-hachi
本番デプロイも成功しました!
参考: Deploying Rails Applications with the Puma Web Server | Heroku Dev Center
関連記事
ちょっと待った! Railsでgitリポジトリから除外すべきでないファイル:Gemfile.lockとdb/schema.rb