LoginSignup
16
9

More than 3 years have passed since last update.

rails5からrails6にアップデートしてはまったところ

Last updated at Posted at 2019-10-18

はじめに

理由ははっきりしてない物もあるけど、テストが通るところまで行ったのでどなたかの役に立つかもしれないのでメモ残してきます。理由が分かってないものはもしかしたらもっとまっとうな解決方法があるかも。

参考資料

Ruby on Rails 6.0 リリースノート

※とりあえずあんまり読んでません。実行してエラーに対処していった感じです。

まずやったこと

  • Gemfileのgem 'rails', '~> 5.2'gem 'rails', '~> 6.0'
  • bundle updateを実行
  • rails app:updateを実行。一旦全てのファイルを上書きする。
  • 上記の変更ファイルの差分を見ながらconfig系など必要な記述を戻す。

2019年10月25日追記

rails app:updateを実行。

これを実行してbin/railsbin/rakeなどが上書きされたのですが、何故かそれによってspringが効かなくなってました。diffを見ると下記のようにspringに関する記述が丸っと消えていました。

#!/usr/bin/env ruby
- begin
-   load File.expand_path('../spring', __FILE__)
- rescue LoadError => e
-   raise unless e.message.include?('spring')
- end
APP_PATH = File.expand_path('../config/application', __dir__)
require_relative '../config/boot'
require 'rails/commands'

なんか信用ならないのでbinディレクトリはrails newしてそこから丸っと持ってきてみました。

駄目だったところ

assetsのCSSとJSが読めない

まず私の環境ですがページ固有のCSSやJSはapp/assets/stylesheets|javascripts/controllersというディレクトリを作り、以下にコントローラ名/アクション名.scss|jsなどのファイルをおいて、以下のようにconfig/initializers/assets.rbに書いて読み込んでました。

# config/initializers/assets.rb

Rails.application.config.assets.precompile += %w[controllers/*]

これが読み込めなくなりました。エラーはこんな感じ

Asset `controllers/books/staff.css` was not declared to be precompiled in production.
Declare links to your assets in `app/assets/config/manifest.js`.

  //= link controllers/books/staff.css
and restart your server

エラー文の通り修正しても動くのですが、config/initializers/assets.rbでも動くので、とりあえず今まで通りconfig/initializers/assets.rbでやってみました。ただ、*で全部読み込むのが何故か分かりませんが、効きません(ざっくりリリースノートを見た感じなさそうだった)。そこで下記のように強引に?対応しました。

# config/initializers/assets.rb

[File.join('app', 'assets', 'stylesheets'), File.join('app', 'assets', 'javascripts')].each do |dir|
  Dir.glob("#{dir}/controllers/**/*")
    .select {|p| p =~ /\.(js|css|scss|erb)$/ && p.exclude?('/_') }
    .map {|p| p.gsub(/\.s?(css|js)(\.erb|)$/, '.\1').gsub("#{dir}/", '') }
    .each do |file|
      Rails.application.config.assets.precompile += [file]
    end
end

app/assets/stylesheets|javascripts/controllers以下のファイルで_で始まっていない物を全てRails.application.config.assets.precompileに突っ込んでます。

突っ込む時は

  • 拡張しscssをcssに置換し、erbがついていたら外す。
  • app/assets/stylesheets|javascriptsからの相対パスに変更。

という処理をしてるのでちょっと読みづらいです。

migrationでエラー

これはちょっと特殊な問題で普通の人ははまらないと思いますが、rails6での変更なので一応書いておきます。

create_tableの時にコピペミスして、同じカラムの定義が二行有るところがありました。rails5の時は無視されていましたが6からエラーをはくようになったようです。

    create_table "work_style", id: :integer, unsigned: true, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" do |t|
      t.bigint "user_id", null: false, unsigned: true
      ...
      t.time "sat_start_time", null: false
      t.integer "sat_hours", null: false, limit: 1, unsigned: true
      t.time "sat_start_time", null: false
      t.integer "sat_hours", null: false, limit: 1, unsigned: true
      ...
      t.index "user_id", unique: true
    end

一部を抜粋しましたがこういうのがエラーになるようになりました。

rails aborted!
StandardError: An error has occurred, all later migrations canceled:

you can't define an already defined column 'sat_start_time'.
/Users/masamoto/Documents/repos/home/source/sites/book-on-rails/db/migrate/20171119023508_create_tables.rb:260:in `block in change'
/Users/masamoto/Documents/repos/home/source/sites/book-on-rails/db/migrate/20171119023508_create_tables.rb:244:in `change'
bin/rails:4:in `require'
bin/rails:4:in `<main>'

Caused by:
ArgumentError: you can't define an already defined column 'sat_start_time'.
/Users/masamoto/Documents/repos/home/source/sites/book-on-rails/db/migrate/20171119023508_create_tables.rb:260:in `block in change'
/Users/masamoto/Documents/repos/home/source/sites/book-on-rails/db/migrate/20171119023508_create_tables.rb:244:in `change'
bin/rails:4:in `require'
bin/rails:4:in `<main>'
Tasks: TOP => db:migrate:reset => db:migrate
(See full trace by running task with --trace)

ControllerSpecのgetでwrong number of arguments

エラーメッセージはこんな感じ。

Failure/Error: get :show, params: { locale: :en, user_id: user.id, token: url_login.token }

ActionView::Template::Error:
  wrong number of arguments (given 2, expected 1)
# ./spec/controllers/users/url_logins_controller_spec.rb:22:in `block (3 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# ArgumentError:
#   wrong number of arguments (given 2, expected 1)
#   ./spec/controllers/users/url_logins_controller_spec.rb:22:in `block (3 levels) in <top (required)>'

これはこちらのQiitaの記事が参考になりました。

修正はGemfileでrspec-railsを4系にすれば直ります。betaなんで微妙ですが少しの我慢だと思います。

- gem "rspec-rails", '~> 3.7'
+ gem "rspec-rails", '~> 4.0.0.beta2'

SCSSでUndefined variable

これはかなり不可解で、原因はrails6と関係ないかもしれないけど5系の時には確かにならなかったので一応載せておきます。

大分省略しますがSCSSがこんな構造になってます。

app/assets/stylesheets
├── _application.scss
├── _utilities.scss
├── _variables.scss
└── utilities
    └── borders.scss
// _application.scss
@import 'variables';
@import 'utilities';
// _utilities.scss
@import 'utilities/borders';
// _variables.scss
$bm_border_default_color: #888;
// utilities/borders.scss
.bu-bdb-dotted{
  border-bottom: 1px dotted $bm_border_default_color !important;
}

この状態である特定のSeleniumのテストがCircleci上でのみこけました。エラーはこんな感じ。

Failure/Error: border-bottom: 1px dotted $bm_border_default_color !important;

ActionView::Template::Error:
  Error: Undefined variable: "$bm-border-default-color".
          on line 11:29 of app/assets/stylesheets/utilities/borders.scss
          from line 3:9 of app/assets/stylesheets/_utilities.scss
  >>   border-bottom: 1px dotted $bm_border_default_color !important;

     ----------------------------^
./app/assets/stylesheets/utilities/borders.scss:11
------------------
--- Caused by: ---
SassC::SyntaxError:
  Error: Undefined variable: "$bm-border-default-color".
          on line 11:29 of app/assets/stylesheets/utilities/borders.scss
          from line 3:9 of app/assets/stylesheets/_utilities.scss
  >>   border-bottom: 1px dotted $bm_border_default_color !important;

     ----------------------------^
  ./app/assets/stylesheets/utilities/borders.scss:11

不可解なのはローカルでテストを実行すると問題なく通ります。さらにCircleciをRerun job with SSHで実行しSSHでログイン後bundle exec rspecするとテストは通ります。buildから実行されるテストのみ必ずこけます。という事情なのでCircleci側の問題の可能性もありますが・・・

全く原因不明なので何から手をつけていいか分からなかったのですが、カン?でこんなことしたら直りました。

// _utilities.scss
@import 'variables';
@import 'utilities/borders';

一番上のapplication.scssでのみ読んでいたvariables.scssを一つ下の階層でもimportしたら通るようになりました。むううううう・・・気持ち悪い。まあとりあえず通ったので良しとします。

2019/10/18 14:55追記

不可解なのはローカルでテストを実行すると問題なく通ります。さらにCircleciをRerun job with SSHで実行しSSHでログイン後bundle exec rspecするとテストは通ります。

tmp/cache/assetsを削除するとローカルでも同じエラーが再現することを発見しました。そして、二度目実行すると通ります。tmp/cache/assetsの中に何かが出来ると通るんですね。こういうのは大抵キャッシュですよね。とりあえず少し進展したのでメモ。


まだ大量のワーニングが出てますけど以上でテストは通りました。さて・・これからワーニング消していく作業を頑張ろうと思います。

16
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
9