【Rails】railsのバージョンアップのエラー備忘録


初めまして。株式会社LCLのバックエンドエンジニアの身軽なデブです。
今回は会社のアドベントカレンダーということで、最近自分が仕事で行っているRailsのバージョンアップについて備忘録を書きたいと思います。
現在弊社のサービスは、着手当初Rails4,5系で稼働しており、今回の記事では、6.0, 6.1 へバージョンアップを現在しようとしている際にぶつかった問題共有させてもらえればと思います。

#目次
[1.設定ファイル系](#-設定ファイル系)
[2.コードの変更系](#4-コードの変更系)
[3.その他](#-その他系)
[4.廃止したgem等](#-廃止したgem等)
[5.mac編](#-mac編)


# 設定ファイル系
##1. halt_callback_chains_on_return_falseのエラー

```ruby:エラー
:これ！（改行）
<top (required)>': undefined method `halt_callback_chains_on_return_false=' for ActiveSupport:Module (NoMethodError)`
```
Rails 4.2では、Active RecordやActive Modelで「before」系コールバックがfalseを返すと、すべてのコールバックチェーンが停止する仕様でした。この場合、以後「before」系コールバックは実行されず、コールバック内にラップされているアクションも実行されません。
Rails 5.0ではこの副作用が修正され、Active RecordやActive Modelのコールバックでfalseが返ってもコールバックチェーンが停止しなくなりました。その代わり、今後コールバックチェーンはthrow(:abort)で明示的に停止する必要があります。

#### 直し方↓
```ruby:initializers/new_framework_defaults.rb
#ActiveSupport.halt_callback_chains_on_return_false = true
# 上記をコメントアウト
```

##２. raise_on_unfiltered_parametersのエラー
```ruby:エラー
this error: Invalid option key: raise_on_unfiltered_parameters= (RuntimeError)
```
パスパラメータ:controllerと:actionを非推奨に指定。 (Pull Request)
config.action_controller.raise_on_unfiltered_parametersを非推奨に指定。Rails 5.1では既に無効。

#### 直し方↓
```ruby:initializers/new_framework_defaults.rb
#Rails.application.config.action_controller.raise_on_unfiltered_parameters = true
# 上記をコメントアウト
```

# コードの変更系
## 1. Arel::Nodes::Exists がrails6で動作しない
呼び出し方がかわったので、existsの前にarelをつけてください

```ruby:以下に変更
Hoge.get_hogehoge.where(condition).select('1').exists
↓
Hoge.get_hogehoge.where(condition).select('1').arel.exists
```

## 2. join_sourcesのエラー
```ruby:エラー
undefined method `join_sources' for #<CmsArticle::ActiveRecord_Relation:0x00007f8c7c1c8670>
```

### 直し方↓
```ruby:
hoge.join_sources
  ↓
hoge.arel.join_sources
```

## 3. :if や:unlessの場合にstringがサポートされなくなった
```ruby:エラー
Passing string to be evaluated in :if and :unless conditional options is not supported. Pass a symbol for an instance method, or a lambda, proc or block, instead.
```

### 直し方↓
```ruby:
エラー内容そのままにブロックやlambdaを使用する。
☓ if: 'mail.blank?'
○ if: proc { |s| s.mail.blank? }
```


## 4. where.notがNORとして動作していたのがdeprecateになりました。Rails 6.1ではNANDとして動作するようになりました。
```ruby:エラー
>> Post.where.not(source_type: "Feed", source_id: 100)
DEPRECATION WARNING: NOT conditions will no longer behave as NOR in Rails 6.1. To continue using NOR conditions, NOT each conditions manually (`.where.not(:source_type => ...).where.not(:source_id => ...)`). (called from irb_binding at (irb):1)
=> #<ActiveRecord::Relation []>
```

### 直し方↓
```ruby:notを複数にして分割する
>> Post.where.not(source_type: "Feed").where.not(source_id: 100)
```

## 5. Rails 5.2から引用符で囲まれていないクラス名をclass_name：を受け付けない
```ruby:エラー
ActionView::Template::Error - A class was passed to `:class_name` but we are expecting a string.:
```

### 直し方↓
```ruby:
   :class_name => ExternalLink
    ↓
   class_name: ‘ExternalLink’
```

## 6. errorのメッセージで配列を作成している箇所
```ruby:エラー
undefined method `[]=' for #<ActiveModel::Errors:0x00007fe7a68ddfe8>
Did you mean?  []
```

### 直し方↓
```ruby:修正
@info_article.errors[:success] = ‘記事を更新しました’
  　　　　　　↓
@info_article.errors.add(:success, “記事を更新しました“)
```

## 7. delete_allの使い方変更
```ruby:エラー
wrong number of arguments (given 1, expected 0)
```
delete_allを末尾にしてwhereに変更

### 直し方↓
```ruby:修正
Test.where(article_id: id).joins(:keyword).delete_all(['name NOT IN (?)', keywords])
   ↓
Test.where(article_id: id).joins(:keyword).where("cms_keywords.name not in (?)", keywords).delete_all
```

## 8. where_valuesが使用できなくなった
```ruby:エラー
undefined method `where_values' for #<Bus::ActiveRecord_Relation:0x00007fc67f96ae40>
Did you mean?  where_values_hash
```

### 直し方↓
```ruby:修正
where(@buses.where_values.reduce(:and))
　　↓
where(@buses.where_clause.send(:predicates).reduce(:and))
```


## 9. manifestのエラー
```ruby:エラー
bundle/ruby/2.7.0/gems/sprockets-rails-3.2.1/lib/sprockets/railtie.rb:105:in `block in <class:Railtie>': Expected to find a manifest file in `app/assets/config/manifest.js` (Sprockets::Railtie::ManifestNeededError)
But did not, please create this file and use it to link any assets that need
to be rendered by your app:
Example:
  //= link_tree ../images
  //= link_directory ../javascripts .js
  //= link_directory ../stylesheets .css
and restart your server
```

### 直し方↓
```ruby:
app/assets/config/manifest.jsを 作成する
```


## 10. before_filterは廃止
```ruby:エラー
ERROR NoMethodError: undefined method `before_filter' for ApplicationController:Class\nDid you mean?  before_action
```

### 直し方↓
```ruby:
before_filter → before_action
```

## 11. deviceのforメソッドについて
```ruby:エラー
undefined method `for' for #<Devise::ParameterSanitizer:0x00007fade3ba93c8>
```
for をpermitに変更
https://github.com/heartcombo/devise#strong-parameters
### 直し方↓
```ruby:
    devise_parameter_sanitizer.for(:sign_up) { |u|
      u.permit(:login_id, :email, :password, :password_confirmation)
    }
　　　　　　　　　　　　　　　　　　　↓
    devise_parameter_sanitizer.permit(:sign_up) do |user_params|
      user_params.permit(:login_id, :email, :password, :password_confirmation)
    end
```

## 12. datepickerのパスが変わった
```ruby:エラー
Sprockets::FileNotFound: couldn't find file 'jquery-ui/datepicker' with type 'application/javascript'
Checked in these paths
```

### 直し方↓
```ruby:app/assets/javascripts/application.js
//= require jquery-ui/datepicker
  ↓
//= require jquery-ui/widgets/datepicker
```

## 13. sourceディレクテブ追加のエラー
```ruby:エラー
Ambiguous source reflection for through association. Please specify a :source directive on your declaration like:
  class GGGG < ActiveRecord::Base
    has_many :payment_methods, {:through=>:hoge_payment_methods, :source=>"payment_method"}
  end
```

### 直し方↓
```ruby:
sourceをつける
-  has_many :payment_methods, :through => :hoge_payment_methods
+  has_many :payment_methods, {:through=>:hoge_payment_methods, :source=>“payment_method”}
```



# その他系
##1. factory_botのデーターフォーマットエラー
```ruby:エラー
undler: failed to load command: unicorn_rails (/Users/goshi/work/busportal-navi/vendor/bundler/ruby/2.7.0/bin/unicorn_rails)
NoMethodError: undefined method ‘booking_site_bus_id’ in ‘promotion_bus’ factory
Did you mean? ‘booking_site_bus_id { 0 }’
```
factory_botのデータはすべて{}で囲う必要あり

### 直し方↓
```ruby:spec/factories/以下
-  booking_site_bus_id 0
+  booking_site_bus_id {0}
```

## 2. rails sできなくなった
```ruby:エラー
vendor/bundle/ruby/2.7.0/gems/activesupport-6.0.3.1/lib/active_support/dependencies.rb:324:in `require': cannot load such file -- hashie/hash (LoadError)
```
以下を追加してbundle install

### 直し方↓
```ruby:Gemfile
gem ‘hashie’
```


# 廃止したgem等
## 1. alias_method_chain is deprecated
alias_method_chainが使用できなくなりましたが、本ブランチではforeinerのgemでのみ使用していた。

参考: [gem foreiner](https://github.com/matthuhiggins/foreigner "gem foreiner")

rails4.2にて廃止されており、rails5.1から外部キーのサポートしている

参考: [gem 外部キーのサポート](https://railsguides.jp/upgrading_ruby_on_rails.html#%E5%A4%96%E9%83%A8%E3%82%AD%E3%83%BC%E3%81%AE%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88 "gem 外部キーのサポート")

## 2. kakurenbo は使用できない
```ruby:エラー
vendor/bundle/ruby/2.7.0/gems/kakurenbo-0.2.3/lib/kakurenbo/mixin_ar_associations.rb:6:in `block in included': undefined method `alias_method_chain' for ActiveRecord::Associations::Association:Class (NoMethodError)
Did you mean?  alias_method
```

### 直し方↓
```ruby:
# gem ‘kakurenbo’　コメントアウト
```

# mac編
## 1. pgエラー
```ruby:エラー
An error occurred while installing therubyracer (0.12.3), and Bundler cannot continue.
Make sure that `gem install therubyracer -v '0.12.3' --source 'https://rubygems.org/'` succeeds before
bundling.
```

### 直し方↓
```ssh:Terminalコマンド
brew install postgresql
```

## 2. pgエラー2
```ruby:エラー
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
    current directory: bundler/ruby/2.7.0/gems/pg-1.2.3/ext
.rbenv/versions/2.7.2/bin/ruby -I .rbenv/versions/2.7.2/lib/ruby/2.7.0 -r
./siteconf20201125-58852-173m77x.rb extconf.rb --with-pg-config\=/usr/local/Cellar/postgresql/12.3_4/bin/pg_config
Using config values from /usr/local/Cellar/postgresql/12.3_4/bin/pg_config
sh: /usr/local/Cellar/postgresql/12.3_4/bin/pg_config: No such file or directory
sh: /usr/local/Cellar/postgresql/12.3_4/bin/pg_config: No such file or directory
```

### 直し方↓
```ssh:Terminalコマンド
$ which pg_config
  /usr/local/bin/pg_config
$ bundle config build.pg  --with-pg-config=/usr/local/bin/pg_config
```

## 3. therubyracer , libv8のエラー
```ruby:エラー
An error occurred while installing therubyracer (0.12.3), and Bundler cannot continue.
Make sure that `gem install therubyracer -v '0.12.3' --source 'https://rubygems.org/'` succeeds before
bundling.
```
macデフォルトのgccが古いため起こる模様

gccを新規インストールしてパスを変更する
.bundle/configに設定を追加する
bundle install

### 直し方↓
```ssh:Terminalコマンド
brew install gcc
ln -s /usr/local/bin/gcc-9 /usr/local/bin/gcc
ln -s /usr/local/bin/g++-9  /usr/local/bin/g++
brew install v8-315
```

```ssh:.bundle/configを編集
---
BUNDLE_BUILD__LIBV8: "--with-system-v8"
BUNDLE_BUILD__THERUBYRACER: "--with-v8-dir=/usr/local/opt/v8@3.15"
```


## 4. ruggedエラー 
```ruby:エラー
An error occurred while installing rugged (1.0.0), and Bundler cannot continue.
Make sure that `gem install rugged -v '1.0.0' --source 'https://rubygems.org/'` succeeds before bundling.
```
cmake追加でなおる模様

### 直し方↓
```ssh:Terminalコマンド
brew reinstall gcc
brew install cmake
```


## 5. nokogiriエラー 
```ruby:エラー
Installing nokogiri 1.10.10 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
    current directory: vendor/bundler　/ruby/2.7.0/gems/nokogiri-1.10.10/ext/nokogiri
/Users/goshi/.rbenv/versions/2.7.2/bin/ruby -I /Users/goshi/.rbenv/versions/2.7.2/lib/ruby/2.7.0 -r
./siteconf20201125-45870-1adiffq.rb extconf.rb
checking if the C compiler accepts  -I /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/libxml2... yes
checking if the C compiler accepts -Wno-error=unused-command-line-argument-hard-error-in-future... no
Building nokogiri using packaged libraries.
Using mini_portile version 2.4.0
checking for iconv.h... yes
checking for gzdopen() in -lz... yes
checking for iconv... yes
************************************************************************
IMPORTANT NOTICE:
Building Nokogiri with a packaged version of libxml2-2.9.10
with the following patches applied:
	- 0001-Revert-Do-not-URI-escape-in-server-side-includes.patch
	- 0002-Remove-script-macro-support.patch
	- 0003-Update-entities-to-remove-handling-of-ssi.patch
	- 0004-libxml2.la-is-in-top_builddir.patch
	- 0005-Fix-infinite-loop-in-xmlStringLenDecodeEntities.patch
Team Nokogiri will keep on doing their best to provide security
updates in a timely manner, but if this is a concern for you and want
to use the system library instead; abort this installation process and
reinstall nokogiri as follows:
```

### 直し方↓
```ssh:Terminalコマンド
bundle config build.nokogiri --use-system-libraries
その後bundle install
```