はじめに
Rails入門として非常にメジャーなRuby on Rails チュートリアルですが、Rails5.1と、3年前のバージョンがベースになっています。
それと比較し、Railsの最新バージョンは記事執筆現在6.0.2です。
マイナーバージョンならまだしも、メジャーバージョンも5→6となっているため、これからRailsを学ぶ方はRails6をベースに学習したいのではないでしょうか。
というわけで、Rails5.1で書かれたチュートリアルを、Rails6.0で動かした際に詰まるポイントをまとめました。
ですが、このページを常に開きながら、詰まった時にすぐに見て…というやり方はあまりオススメしません。
なぜなら詰まった時にこそ、エラーを読んでいろいろ調べることで得られる知識も多いためです。
詰まった際に15分、20分と解決しなかった際に本記事を参照いただけると幸いです。
なお、大前提、AWS Cloud9の構築です。
■1章
sqlite3のバージョンエラー
Cloud9の環境構築時にPlatformデフォルトがAmazon Linuxになっていますが、Ubuntuを選びましょう。
Amazon Linuxを選ぶとRails6入れた際のsqlite3のバージョンが足りず詰まります。
bundle installとかでなんかコケる
とりあえず
リスト 1.4: hello_appディレクトリにあるデフォルトのGemfile
はガン無視して、Rails6でアプリケーション作ったまま何も弄らず実行しましょう。
rails s(server)を実行したけどアプリケーションが動かない
図 1.12: アプリケーションをブラウザで開いたときの画面
このスクショをよく見ましょう。
Cloud9の分割ウィンドウでは実行結果が見れず、新規ウィンドウで開かないと見れません。
rails sでアプリケーション開いたけど謎エラー To allow requests to xxxxxxxxxx〜〜〜
To allow requests to xxxxxxxxxx.cloud9.ap-northeast-1.amazonaws.com, add the following to your environment configuration:
Rails6からconfigに自身のhost書かないと弾かれます
module HelloApp
class Application < Rails::Application
...
+ config.hosts << '.amazonaws.com'
...
end
end
書いただけでは即座に反映されないので、rails sをCtrl+Cで一旦止めて、再度rails s実行
productionのPostgresとdevelopmentのsqlite3
チュートリアルでは
gem 'sqlite3', '1.3.13'
となっていますが、
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.2', '>= 6.0.2.1'
-# Use sqlite3 as the database for Active Record
-gem 'sqlite3', '~> 1.4'
...
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
+ # Use sqlite3 as the database for Active Record
+ gem 'sqlite3', '~> 1.4'
end
...
+ group :production do
+ gem 'pg', '0.20.0'
+ end
こうなりますね
herokuでもhost弾かれる
同じくhostが弾かれるので、
module HelloApp
class Application < Rails::Application
...
config.hosts << '.amazonaws.com'
+ config.hosts << '.herokuapp.com'
...
end
end
■2章
最初のGemfile、そしてhost問題は上記と同じ対応で解決
■3章
3章でも最初のGemfile、そしてhost問題は1章と同じ対応で解決
テストが403でコケる
Failure:
StaticPagesControllerTest#test_should_get_home [/home/ubuntu/environment/sample_app/test/controllers/static_pages_controller_test.rb:6]:
Expected response to be a <2XX: success>, but was a <403: Forbidden>
試しにhostのチェックをしないconfig.hosts.clearを追加すると、コケずに通ります。
ということはやはりここが原因で、test時のhostはamazonaws.comではないためにコケている模様。
Cloud9のaws.amazon.comを追加しても動かないので、testで
test "should get home" do
get static_pages_home_url
+ p request.host_with_port
assert_response :success
end
これで実行すると
rails test test/controllers/static_pages_controller_test.rb:10
"www.example.com"
と出ます。
どうやらtestはwww.example.comで実行される模様。よって
module HelloApp
class Application < Rails::Application
...
config.hosts << '.amazonaws.com'
config.hosts << '.herokuapp.com'
+ config.hosts << 'www.example.com'
...
end
end
これでOKです。
2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
リスト 3.35:付近 app/views/layouts/application.html.erbを直した後にtestがコケる
ActionView::Template::Error: The asset "application.js" is not present in the asset pipeline.
jsタグの書き方が変わっているので、サンプルそのままコピペだと動かないです。
- <%# javascript_include_tag 'application',
- 'data-turbolinks-track': 'reload' %>
+ <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
Rails6でrails newした時のデフォルト記述に戻す。これでOK
minitest reportersがコケる
エラーの最終行をよく読む
/home/ubuntu/.rvm/gems/ruby-2.6.3/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:34:in `require': cannot load such file -- minitest/reporters (LoadError)
GemfileをRails6でrails newした関係でいじっていなかったことを思い出す。
入れましょう。
group :test do
# Adds support for Capybara system testing and selenium driver
gem 'capybara', '>= 2.15'
gem 'selenium-webdriver'
# Easy installation and use of web drivers to run system tests with browsers
gem 'webdrivers'
+ gem 'minitest', '5.10.3'
+ gem 'minitest-reporters', '1.1.14'
+ gem 'guard', '2.13.0'
+ gem 'guard-minitest', '2.4.4'
end
$ bundle install
$ rails t
Running via Spring preloader in process 4865
Started with run options --seed 879
5/5: [==================================================================================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.12243s
5 tests, 9 assertions, 0 failures, 0 errors, 0 skips
OK。
Guard入れる時にyum使えない
$ sudo yum install -y tmux
sudo: yum: command not found
この記事の通りに進めていたらAmazon LinuxではなくUbuntuのはず。
なのでyumではなくapt-get使いましょう
$ sudo apt-get install -y tmux
Guardのexecでコケる
/home/ubuntu/.rvm/gems/ruby-2.6.3/gems/guard-2.13.0/lib/guard/jobs/pry_wrapper.rb:131:in `_setup': undefined method `file=' for #<Pry::History:0x000055a6b08de940>
Did you mean? filter (NoMethodError)
みたいなエラー。
よく分からなかったのでググったらQiita記事ヒット。
Ruby on Rails チュートリアル 3章のguardがエラーで失敗する
こちら参考に、Guardのバージョンを最新に上げればOK
group :test do
# Adds support for Capybara system testing and selenium driver
gem 'capybara', '>= 2.15'
gem 'selenium-webdriver'
# Easy installation and use of web drivers to run system tests with browsers
gem 'webdrivers'
gem 'minitest', '5.10.3'
gem 'minitest-reporters', '1.1.14'
- gem 'guard', '2.13.0'
+ gem 'guard', '2.16.2'
gem 'guard-minitest', '2.4.4'
end
■4章
layout編集してjavascriptタグでコケた場合は3章参照
■5章
4章と同じく。
layout編集してjavascriptタグでコケた場合は3章参照
統合テストでコケる
NoMethodError: NoMethodError: assert_template has been extracted to a gem. To continue using it,
add `gem 'rails-controller-testing'` to your Gemfile.
assert_templateメソッドはGemから取り除かれたよ、使いたければ'rails-controller-testing'をGemfileに追加してくれとのこと。
+ gem 'rails-controller-testing'
■6章
bcryptの追加
rails newした時からgemの追加のみ行っている場合、bcryptがコメントアウトで最初から記載されているはず。
コメントアウト外してbundle installするだけでOKです。
■7章
特筆事項無し
■8章
jQueryとbootstrapの入れ方が異なる。
こちらの記事を参考に。
Rails 6 webpack throwing 'Uncaught ReferenceError: $ is not defined'
まずはyarnでjquery, bootstrap, popper.jsを入れる
$ yarn add jquery bootstrap popper.js
const { environment } = require('@rails/webpacker')
+ const webpack = require('webpack')
+ environment.plugins.prepend('Provide', new webpack.ProvidePlugin({
+ $: 'jquery/src/jquery',
+ jQuery: 'jquery/src/jquery',
+ jquery: 'jquery',
+ 'window.jQuery': 'jquery',
+ Popper: ['popper.js', 'default']
+ }))
module.exports = environment
...
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
+ import 'bootstrap';
...
これでログインのプルダウンが動く。
■9章
特筆事項なし
■10章
10.7やった後、統合テストがコケる
FAIL["test_invalid_signup_information", UsersSignupTest, 0.87976424199951]
test_invalid_signup_information#UsersSignupTest (0.88s)
Expected at least 1 element matching "form[action="/signup"]", found 0..
Expected 0 to be >= 1.
Rails6起因ではありませんが、マジメに1章から9章までの全演習をやっているとリスト10.7までやったところでテストがコケるようになります。
原因はformをpartial化した際、@userのルーティングによって新規登録時にsignup_pathじゃなく、これが適用されてしまうためです。
POST /users(.:format) users#create
formの飛び先をpartialに渡しましょう。
参考:Railsチュートリアル第10章10.1.2でtestが通らなかった話
formの飛び先を指定するため、わかりやすくform_urlという名前にしました。
- <%= form_for(@user) do |f| %>
+ <%= form_for(@user, url: yield(:form_url)) do |f| %>
+ <% provide(:form_url, signup_path) %>
+ <% provide(:form_url, user_path) %>
これでintegration testが再び通過するようになります。
fakerのbundle installがコケる
バージョンが古いのが原因。調べたところ執筆時点で2.11が最新なので変更。
+ gem 'faker', '2.11'
will_pagenateが動かない
will_pagenate wrong number of arguments (given 0, expected 1)
引数1個必要なのに0個だよ、というエラー。
普通に開発している時はソースコードの方を疑うべきですが、Rails Tutorialの表記でソースコード自体が間違っていることは考えづらいです。
ということで、そろそろあたりが付けられるようになるかと思いますが、これもバージョンの関係です。
執筆時点でwill_paginateは3.3.0が最新なので変更。
+ gem 'will_paginate', '3.3.0'
■11章
特筆事項なし
■12章
特筆事項なし
■13章
リスト13.18のテストがコケる
Rail6特有かどうか分かりませんが、リスト13.15のfixtureでユーザーを指定しないため、以下エラーが起きます。
ActiveRecord::NotNullViolation: ActiveRecord::NotNullViolation: RuntimeError: NOT NULL constraint failed: microposts.user_id
orange:
content: "I just ate an orange!"
created_at: <%= 10.minutes.ago %>
+ user: one
tau_manifesto:
content: "Check out the @tauday site by @mhartl: http://tauday.com"
created_at: <%= 3.years.ago %>
+ user: one
cat_video:
content: "Sad cats are sad: http://youtu.be/PKffm2uI4dk"
created_at: <%= 2.hours.ago %>
+ user: one
most_recent:
content: "Writing a short test"
created_at: <%= Time.zone.now %>
+ user: one
サンプルデータにマイクロポスト追加で非推奨エラーが大量に出る
/home/ubuntu/environment/sample_app/db/seeds.rb:30: Passing `word_count` with the 1st argument of `sentence` is deprecated. Use keyword argument like `sentence(word_count: ...)` instead.
To automatically update from positional arguments to keyword arguments,
install rubocop-faker and run:
rubocop \
--require rubocop-faker \
--only Faker/DeprecatedArguments \
--auto-correct
word_count
...
+ users = User.order(:created_at).take(6)
+ 50.times do
+ content = Faker::Lorem.sentence(word_count: 5)
+ users.each { |user| user.microposts.create!(content: content) }
+ end
そのすぐ先にあるfixtureも以下のように。
...
content: <%= Faker::Lorem.sentence(word_count: 5) %>
...
画像入れた後のテストがコケる
テストがうまく動かなくなるケースがあります(これもRails6に限らず、起きるケースがある模様)
ERROR["test_should_get_about", StaticPagesControllerTest, 0.012211428000227897]
test_should_get_about#StaticPagesControllerTest (0.01s)
NameError: NameError: uninitialized constant #<Class:0x00007f6628771790>::PictureUploader
Did you mean? Micropost::Preloader
app/models/micropost.rb:4:in `<class:Micropost>'
app/models/micropost.rb:1:in `<main>'
FAIL["test_content_should_be_at_most_140_characters", MicropostTest, 0.7875548960000742]
test_content_should_be_at_most_140_characters#MicropostTest (0.79s)
Expected true to be nil or false
test/models/micropost_test.rb:26:in `block in <class:MicropostTest>'
FAIL["test_user_id_should_be_present", MicropostTest, 0.7924731410003005]
test_user_id_should_be_present#MicropostTest (0.79s)
Expected true to be nil or false
test/models/micropost_test.rb:16:in `block in <class:MicropostTest>'
FAIL["test_content_should_bepresent", MicropostTest, 0.7981856210008118]
test_content_should_bepresent#MicropostTest (0.80s)
Expected true to be nil or false
test/models/micropost_test.rb:21:in `block in <class:MicropostTest>'
こちらを参考に解決します。
Railsチュートリアル中にNameError: uninitialized constant Micropost::PictureUploaderが出た時の対処法
springを再起動すれば直ることがある模様です。
$ spring stop
$ spring server
※参考記事ではspring startとなっていますが、現バージョンではspring serverとなっている模様
ImageMagickが入れられない
cloud9でUbuntuでやっている場合、yumじゃなくapt-getになります。
単純に置き換えるとImageMagickは無いというエラーになります。apt-getだと小文字のよう。
$ sudo apt-get -y install imagemagick
これでOKです。
■14章
フォローのAjax化が動かない
開発者ツールのコンソールを見ると
uncaught referenceerror $ is not defined
8章の手順に沿って対応すればOK