初めまして。株式会社LCLのバックエンドエンジニアの身軽なデブです。
今回は会社のアドベントカレンダーということで、最近自分が仕事で行っているRailsのバージョンアップについて備忘録を書きたいと思います。
現在弊社のサービスは、着手当初Rails4,5系で稼働しており、今回の記事では、6.0, 6.1 へバージョンアップを現在しようとしている際にぶつかった問題共有させてもらえればと思います。
#目次
1.設定ファイル系
2.コードの変更系
3.その他
4.廃止したgem等
5.mac編
設定ファイル系
##1. halt_callback_chains_on_return_falseのエラー
:これ!(改行)
<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)で明示的に停止する必要があります。
直し方↓
#ActiveSupport.halt_callback_chains_on_return_false = true
# 上記をコメントアウト
##2. raise_on_unfiltered_parametersのエラー
this error: Invalid option key: raise_on_unfiltered_parameters= (RuntimeError)
パスパラメータ:controllerと:actionを非推奨に指定。 (Pull Request)
config.action_controller.raise_on_unfiltered_parametersを非推奨に指定。Rails 5.1では既に無効。
直し方↓
#Rails.application.config.action_controller.raise_on_unfiltered_parameters = true
# 上記をコメントアウト
コードの変更系
1. Arel::Nodes::Exists がrails6で動作しない
呼び出し方がかわったので、existsの前にarelをつけてください
Hoge.get_hogehoge.where(condition).select('1').exists
↓
Hoge.get_hogehoge.where(condition).select('1').arel.exists
2. join_sourcesのエラー
undefined method `join_sources' for #<CmsArticle::ActiveRecord_Relation:0x00007f8c7c1c8670>
直し方↓
hoge.join_sources
↓
hoge.arel.join_sources
3. :if や:unlessの場合にstringがサポートされなくなった
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.
直し方↓
エラー内容そのままにブロックやlambdaを使用する。
☓ if: 'mail.blank?'
○ if: proc { |s| s.mail.blank? }
4. where.notがNORとして動作していたのがdeprecateになりました。Rails 6.1ではNANDとして動作するようになりました。
>> 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 []>
直し方↓
>> Post.where.not(source_type: "Feed").where.not(source_id: 100)
5. Rails 5.2から引用符で囲まれていないクラス名をclass_name:を受け付けない
ActionView::Template::Error - A class was passed to `:class_name` but we are expecting a string.:
直し方↓
:class_name => ExternalLink
↓
class_name: ‘ExternalLink’
6. errorのメッセージで配列を作成している箇所
undefined method `[]=' for #<ActiveModel::Errors:0x00007fe7a68ddfe8>
Did you mean? []
直し方↓
@info_article.errors[:success] = ‘記事を更新しました’
↓
@info_article.errors.add(:success, “記事を更新しました“)
7. delete_allの使い方変更
wrong number of arguments (given 1, expected 0)
delete_allを末尾にしてwhereに変更
直し方↓
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が使用できなくなった
undefined method `where_values' for #<Bus::ActiveRecord_Relation:0x00007fc67f96ae40>
Did you mean? where_values_hash
直し方↓
where(@buses.where_values.reduce(:and))
↓
where(@buses.where_clause.send(:predicates).reduce(:and))
9. manifestのエラー
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
直し方↓
app/assets/config/manifest.jsを 作成する
10. before_filterは廃止
ERROR NoMethodError: undefined method `before_filter' for ApplicationController:Class\nDid you mean? before_action
直し方↓
before_filter → before_action
11. deviceのforメソッドについて
undefined method `for' for #<Devise::ParameterSanitizer:0x00007fade3ba93c8>
for をpermitに変更
https://github.com/heartcombo/devise#strong-parameters
直し方↓
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のパスが変わった
Sprockets::FileNotFound: couldn't find file 'jquery-ui/datepicker' with type 'application/javascript'
Checked in these paths
直し方↓
//= require jquery-ui/datepicker
↓
//= require jquery-ui/widgets/datepicker
13. sourceディレクテブ追加のエラー
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
直し方↓
sourceをつける
- has_many :payment_methods, :through => :hoge_payment_methods
+ has_many :payment_methods, {:through=>:hoge_payment_methods, :source=>“payment_method”}
その他系
##1. factory_botのデーターフォーマットエラー
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のデータはすべて{}で囲う必要あり
直し方↓
- booking_site_bus_id 0
+ booking_site_bus_id {0}
2. rails sできなくなった
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
直し方↓
gem ‘hashie’
廃止したgem等
1. alias_method_chain is deprecated
alias_method_chainが使用できなくなりましたが、本ブランチではforeinerのgemでのみ使用していた。
参考: gem foreiner
rails4.2にて廃止されており、rails5.1から外部キーのサポートしている
参考: gem 外部キーのサポート
2. kakurenbo は使用できない
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
直し方↓
# gem ‘kakurenbo’ コメントアウト
mac編
1. pgエラー
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.
直し方↓
brew install postgresql
2. pgエラー2
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
直し方↓
$ which pg_config
/usr/local/bin/pg_config
$ bundle config build.pg --with-pg-config=/usr/local/bin/pg_config
3. therubyracer , libv8のエラー
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
直し方↓
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
---
BUNDLE_BUILD__LIBV8: "--with-system-v8"
BUNDLE_BUILD__THERUBYRACER: "--with-v8-dir=/usr/local/opt/v8@3.15"
4. ruggedエラー
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追加でなおる模様
直し方↓
brew reinstall gcc
brew install cmake
5. nokogiriエラー
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:
直し方↓
bundle config build.nokogiri --use-system-libraries
その後bundle install