はじめに
この記事は、タイトルのとおり、「Everyday Rails」を Rails 6 で勉強したいので、
書籍の翻訳者である伊藤さんのブログを参考にして頑張ってみた記録を記したものである。
記事自体が長くなったので、導入編・前編・中編・後編に分割している。
Rails 6 へのアップグレードは非常に時間がかかるので、いきなり挑戦するのではなく、
まず導入編を読んでいただき、本当に挑戦するのか検討することを強く勧めます。
記録を見たい方は、以下を参照すること。
【導入編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita
【前編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita
【後編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita
また、本記事は、伊藤さんのyoutube動画を見ながら作業した内容の実況中継に
近いような形で書き進めているので、以下を必ず併せて視聴してください。
(youtube動画を視聴している前提で書いているので、この記事単体だと意味が通じない)
【前編】永久保存版!?伊藤さん式・Railsアプリのアップグレード手順(youtube動画)
【後編】永久保存版!?伊藤さん式・Railsアプリのアップグレード手順(youtube動画)
4. Rails以外のgemをバージョンアップする
4-c. トラブルが起きやすそうなgemを1つずつアップデートする
RSpecのサンプルアプリでなければ慎重にやるべきなのだが、
動画内で伊藤さんはスルーしていたので、割愛する。
ただ、gemを見つつ、アップデートでトラブルが起きそうでないか確認をしていた。
そういうステップがあるということだけ確認しつつ、次へ進むことにする。
4-d. その他のgemをまとめてアップデートする
伊藤さんによると、次はbundle outdated | bof --format markdown
の実行によって取得できた default と書いてあるgem
を見ていくべきとのことだが、
そもそも default と書かれているgem
が存在しない。
参考までに、伊藤さんの動画のスクリーンショットと、
私が取得した default と書かれていないgem
の一覧を貼付しておく。
勝手な推測だが、伊藤さんが動画を撮った時期と、
私がアップデートしている時期が異なるためだと思われる。
(それか何か余計な操作をしてしまったのかもしれない)
【自分でやってみた結果】
gem | newest | installed | requested | groups |
---|---|---|---|---|
actioncable | 6.0.3.1 | 5.1.7 | ||
actionmailer | 6.0.3.1 | 5.1.7 | ||
actionpack | 6.0.3.1 | 5.1.7 | ||
actionview | 6.0.3.1 | 5.1.7 | ||
activejob | 6.0.3.1 | 5.1.7 | ||
activemodel | 6.0.3.1 | 5.1.7 | ||
activerecord | 6.0.3.1 | 5.1.7 | ||
activesupport | 6.0.3.1 | 5.1.7 | ||
arel | 9.0.0 | 8.0.0 | ||
autoprefixer-rails | 9.7.6 | 6.7.7.2 | ||
bcrypt | 3.1.13 | 3.1.12 | ||
bindex | 0.8.1 | 0.5.0 | ||
bootstrap-sass | 3.4.1 | 3.3.7 | ||
cocaine | 0.6.0 | 0.5.8 | ||
coffee-rails | 5.0.0 | 4.2.1 | ~> 4.2 | |
devise | 4.7.2 | 4.4.3 | ||
faker | 2.12.0 | 1.7.3 | ||
geocoder | 1.6.3 | 1.4.9 | ||
i18n | 1.8.3 | 0.9.5 | ||
jbuilder | 2.10.0 | 2.6.3 | ~> 2.5 | |
jquery-rails | 4.4.0 | 4.3.1 | ||
listen | 3.2.1 | 3.1.5 | < 3.2, >= 3.0.5 | |
mimemagic | 0.3.5 | 0.3.2 | ||
mini_portile2 | 2.5.0 | 2.4.0 | ||
multi_json | 1.14.1 | 1.12.1 | ||
paperclip | 6.1.0 | 5.1.0 | ||
puma | 4.3.5 | 3.8.2 | ~> 3.7 | |
rails | 6.0.3.1 | 5.1.7 | ~> 5.1.1 | |
railties | 6.0.3.1 | 5.1.7 | ||
rb-fsevent | 0.10.4 | 0.9.8 | ||
rb-inotify | 0.10.1 | 0.9.8 | ||
responders | 3.0.1 | 2.4.0 | ||
sass | 3.7.4 | 3.4.23 | ||
sass-rails | 6.0.0 | 5.0.6 | ~> 5.0 | |
spring | 2.1.0 | 2.0.1 | ||
sprockets | 4.0.2 | 3.7.2 | ||
sqlite3 | 1.4.2 | 1.3.13 | ||
thor | 1.0.1 | 0.20.3 | ||
tilt | 2.0.10 | 2.0.7 | ||
turbolinks | 5.2.1 | 5.0.1 | ~> 5 | |
turbolinks-source | 5.2.0 | 5.0.0 | ||
tzinfo | 2.0.2 | 1.2.7 | ||
uglifier | 4.2.0 | 3.2.0 | ||
warden | 1.2.8 | 1.2.7 | ||
web-console | 4.0.3 | 3.5.0 | ||
websocket-driver | 0.7.2 | 0.6.5 |
この時点でyoutube動画と条件も違うのだが、ここは伊藤さんの動画でやっているとおり、
雑にbundle update
してみることにする。
けど、正直トラブルになりそうで、とても怖い。。。
とりあえず、後で戻せるようにコミットだけしておく。
やってみると、bundle update
は成功した!
続いて、RSpecでのテストを実行する。
Finished in 25.46 seconds (files took 1.14 seconds to load)
70 examples, 0 failures
無事、成功した!!
ただ、動画で説明のとおり、以下のような警告が出ている。
Sign-ups
DEPRECATION WARNING: [Devise] `DeviseHelper.devise_error_messages!`
is deprecated and it will be removed in the next major version.
To customize the errors styles please run `rails g devise:views` and modify the
`devise/shared/error_messages` partial.
ここで、警告に書かれているとおり、 rails g devise:views
を実行する。
実行すると、オーバーライトするか尋ねられる。
最初はn
として、次のファイルにてd
を押して、差分を確認して以下をコピーする。
- <%= devise_error_messages! %>
+ <%= render "devise/shared/error_messages", resource: resource %>
他のファイルについては、全てn
とする。
コピーした内容を使って、関係ファイルの該当部分を修正する。
<%= devise_error_messages! %>
を全て修正する。
修正後は、<%= render "devise/shared/error_messages", resource: resource %>
とする。
該当ファイルは以下のとおり。
修正後にRSpecにてテストを行うと、警告が消えた。
bundle outdated
を行うと、以下のとおりとなった。
gem | newest | installed | requested | groups |
---|---|---|---|---|
actioncable | 6.0.3.1 | 5.1.7 | ||
actionmailer | 6.0.3.1 | 5.1.7 | ||
actionpack | 6.0.3.1 | 5.1.7 | ||
actionview | 6.0.3.1 | 5.1.7 | ||
activejob | 6.0.3.1 | 5.1.7 | ||
activemodel | 6.0.3.1 | 5.1.7 | ||
activerecord | 6.0.3.1 | 5.1.7 | ||
activesupport | 6.0.3.1 | 5.1.7 | ||
arel | 9.0.0 | 8.0.0 | ||
coffee-rails | 5.0.0 | 4.2.2 | ~> 4.2 | |
listen | 3.2.1 | 3.1.5 | < 3.2, >= 3.0.5 | |
mini_portile2 | 2.5.0 | 2.4.0 | ||
puma | 4.3.5 | 3.12.6 | ~> 3.7 | |
rails | 6.0.3.1 | 5.1.7 | ~> 5.1.1 | |
railties | 6.0.3.1 | 5.1.7 | ||
sass-rails | 6.0.0 | 5.0.7 | ~> 5.0 | |
sprockets | 4.0.2 | 3.7.2 | ||
thor | 1.0.1 | 0.20.3 | ||
tzinfo | 2.0.2 | 1.2.7 | ||
web-console | 4.0.3 | 3.7.0 | ||
websocket-driver | 0.7.2 | 0.6.5 |
伊藤さんの動画だと、以下のとおりとなっている。
よく見ると違うところもあるが、概ね同じ状態になった。
5. Rubyのバージョンを最新にする
動画での指示に従い、Rubyのバージョンを新しくする。
現在の最新のバージョン(安定版)は2.7.1とのことだが、試すのも怖い。
(動画では2.6.5が採用されている)
とはいえ、伊藤さんによるとRubyは後方互換性を意識しているとのことなので、
commit
だけ一応しておいて、バージョン2.7.1で試してみる。
# ruby 2.7.1 をダウンロードする
rbenv install 2.7.1
# rubyのバージョンを 2.7.1 に指定する
rbenv local 2.7.1
# rubyのバージョンが 2.7.1 になっていることを確認する
rbenv version
改めて、bundle install
を行う。
すると、gem install bundler 2.1.4
を実行せよと指示が出るので、
その指示に従った後、もう一度bundle install
を行う。
警告が出るが、i18n
, Paperclip
, Sass
に関連するものであり、
Ruby 2.4.9 を導入してbundle
した時の警告と基本的には変わらない。
RSpecでテストを実行する。
Users/HOGE/.rbenv/gems/2.7.0/bundler/gems/shoulda-matchers-4b160bd19ecc/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb:273:in `<class:ValidateInclusionOfMatcher>': undefined method `new' for BigDecimal:Class (NoMethodError)
エラーとなってしまった。
動画上では警告が出るだけだったが、Rubyのバージョンを上げたためなのか、
そもそもRSpecのテストが出来なくなってしまった。
ただ、動画によると、このエラーはRailsのバージョンを上げれば解決するようなので、
Railsを5.2.3にアップデートしてみる。
なお、動画ではGemfile
を開き、shoulda-matchers
のブランチ指定を解除していたが、
そちらについては後ほど対応することとする。
6. Railsを最新のパッチバージョンに上げる
ここは、実は手順4の中でbundle update
をしている中で済んでいる。
実際のアプリでバージョンアップする場合については、
Railsと他のgemのアップデートはきちんと切り分けた方がよいのかもしれない。
7. Railsのメジャーバージョン、またはマイナーバージョンを上げる
Gemfile
を開き、railsのバージョンを以下のとおり設定する。
gem 'rails', '~> 5.2.3'
そして、bundle update
を実行する。
無事、成功した。
8. rails app: update タスクを実行する
終了した後、rails app: update
を実行する。
routes.rb
だけはn
を押し、それ以外はy
を押す。
必要に応じて上書きされた設定を元に戻す
ここで差分を確認しながら、自力で必要な設定を戻していく。
VSCodeを使っていると、以下のとおり確認できる。
動画の指示に従い、設定を以下のとおり戻した。
参考までに記す。
module Projects
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.1
# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
# the framework and any gems in your application.
# configで始まる部分を追加
config.generators do |g|
g.test_framework :rspec,
view_specs: false,
helper_specs: false,
routing_specs: false
end
end
end
# 以下のコードを最後に追加する
# Keep files uploaded in tests from polluting the Rails development
# environment's file uploads
Paperclip::Attachment.default_options[:path] = \
"#{Rails.root}/spec/test_uploads/:class/:id_partition/:style.:extension"
9. railsdiff.org を参考にして、新しく追加された gem 等を確認する
以下のとおり説明があるので、対応する。
app:updateコマンドを実行しても、Gemfileのようにまったく更新されないファイルもあります。
ですが、rails newした直後のGemfileを比較すると、
デフォルトでインストールされるgemの種類やバージョンには違いがあります。
Railsのバージョンを上げたのであれば、こういった部分も新しいRailsに合わせておく方が安心です。
以下を開き、動画のとおり更新する。
正直、初学者にはどれを更新すべきか、全く見当がつかない。
更新した箇所は下記のとおり、3つのファイル。
〜 上部は変更がないので省略 〜
# ---- 以下に修正を加えた ------
# Ignore uploaded files in development # これを追加
/storage/* # これを追加
!/storage/.keep # これを追加
/node_modules
/yarn-error.log
/public/assets # これを追加
.byebug_history
# Ignore master key for decrypting credentials and more. # これを追加
/config/master.key # これを追加
# Ignore uploads from Paperclip
/public/system
/spec/test_uploads
.ruby-version
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" } # ここを変更
ruby '2.7.1' # ここを追加
gem 'rails', '~> 5.2.3'
gem 'sqlite3'
gem 'puma', '~> 3.11' # ここを変更
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.2'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
gem 'bootsnap', '>= 1.1.0', require: false # ここを追加
〜 以下、変更がないので省略します 〜
<!DOCTYPE html>
<html>
<head>
<title>Projects</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
# 以下は変更がないので、省略
さて、変更を終えたので、bundle install
を実行する。
実行したところ、無事終了した。
10. 動作確認を行う
動画に従い、rails c
を実行する。
すると、rails c
の起動は出来たが、以下の警告メッセージが出てきた。
/Users/HOGE/.rbenv/gems/2.7.0/gems/actionpack-5.2.4.3/lib/action_dispatch/middleware/stack.rb:37: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/Users/HOGE/.rbenv/gems/2.7.0/gems/actionpack-5.2.4.3/lib/action_dispatch/middleware/static.rb:111: warning: The called method `initialize' is defined here
また、rails c
の挙動を確認したが、エラーとなった。
irb(main):001:0> User.count
Traceback (most recent call last):
1: from (irb):1
ActiveRecord::StatementInvalid (Could not find table 'users')
動画の中で見逃したのかもしれないが、マイグレーションが必要だったのだろうか。
git
でtest
というブランチを作り、保険だけ掛けておく。
マイグレーションを行うと、無事rails c
は動いた。
ただ、動画とは異なり、User.countをしても 21 という数は出てこない。
きっと伊藤さんはテストか何かをしていて、それでUserが21人もいるのだろう。
また、先ほど出てきた警告メッセージは、引き続き出てくる。
気になったので調べてみると、どうやらgemが対応できていないことが原因らしい。
問題はなさそうなので、とりあえずスルーすることにする。
rails s
にてサーバーが立ち上がるかも確認。
無事動き、機能も一通り試したところ問題がなさそうだった。
bin/rspec
を実行する。
以下のエラーが出て、テストが実行できなかった。
/Users/HOGE/.rbenv/gems/2.7.0/bundler/gems/shoulda-matchers-4b160bd19ecc/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb:273:in `<class:ValidateInclusionOfMatcher>': undefined method `new' for BigDecimal:Class (NoMethodError)
shoulda-matchers
と書いてあるので、ここで放置してきた
shoulda-matchers
のブランチ指定を解除を行ってみる。
Gemfile
を開き、gem 'shoulda-matchers'
以下に書いてある2行のブランチ指定のコードを削除する。
そして、bundle install
を実行する。
すると、テストが無事実行できた。
ただ、以下の失敗が起きた。
また、Rubyのバージョンが2.7.1に上がったことが原因だと推測されるが、大量の警告が出た。
Failures:
1) Notes user uploads an attachment
Failure/Error: fill_in "Message", with: "My book cover"
Capybara::ElementNotFound:
Unable to find field "Message" that is not disabled
〜 省略 〜
2) Projects user creates a new project
Failure/Error: fill_in "Name", with: "Test Project"
Capybara::ElementNotFound:
Unable to find field "Name" that is not disabled
〜 省略 〜
Finished in 46.59 seconds (files took 3.76 seconds to load)
70 examples, 2 failures
Failed examples:
rspec ./spec/system/notes_spec.rb:11 # Notes user uploads an attachment
rspec ./spec/system/projects_spec.rb:4 # Projects user creates a new project
なお、以下の警告も出てきた。
こちらは動画内で取り上げられていたので、Rubyが2.7.1にバージョンアップしたことが原因ではないもよう。
DEPRECATION WARNING: The success? predicate is deprecated and will be removed in Rails 6.0. Please use successful? as provided by Rack::Response::Helpers. (called from block (3 levels) in <main> at /Users/HOGE/Desktop/Github作業フォルダ/RSpecPractice/everydayrails-rspec-2017-master/spec/controllers/tasks_controller_spec.rb:40)
# 他の箇所にもRSpec関係のファイルにて同様の警告があり
動画に従い、まず以下のFailuresから解決する。
Failures:
1) Notes user uploads an attachment
Failure/Error: fill_in "Message", with: "My book cover"
Capybara::ElementNotFound:
Unable to find field "Message" that is not disabled
〜 省略 〜
2) Projects user creates a new project
Failure/Error: fill_in "Name", with: "Test Project"
Capybara::ElementNotFound:
Unable to find field "Name" that is not disabled
これはform_with
に関わるエラーであり、HTMLが生成されるときにidが消えてしまうらしい。
config.load_defaultsとnew_framework_defaults_x_x.rbの関係を詳しく調べてみた - Qiita
そこで、以下のファイルを修正する。
module Projects
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
# 5.1から5.2に変更する
config.load_defaults 5.2
# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
# the framework and any gems in your application.
config.generators do |g|
g.test_framework :rspec,
view_specs: false,
helper_specs: false,
routing_specs: false
end
end
end
RSpecのテストを実行してみると、動画のとおり、全てのテストがパスした。
Finished in 14.12 seconds (files took 1.05 seconds to load)
70 examples, 0 failures
次に、警告を解決する。
改めて英文の警告を確認すると、success
をsuccessful
に書き換えろと指示があるので、
その指示に従う。すると、警告が消えるらしい。
以下のファイルを開き、指示のとおり対応した。
spec/controllers/home_controller_spec.rb
spec/controllers/projects_controller_spec.rb
spec/controllers/tasks_controller_spec.rb
spec/controllers/home_spec.rb
RSpecのテストを実行してみると、警告が消えた。
(もちろん、Ruby2.7.1の導入に起因すると思われる大量の警告は残ったままであるが笑)
これで、Rails5.2へのアップデートが終了した。
どこまで進んだか
動画の後編の12分30秒くらいのところまで進んだ。
【後編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた