Rails 7.0 から 7.1 へのアップグレード時のトラブルと対応策
参考:Rails アップグレードガイド – Railsガイド
Railsバージョンアップ
- gem 'rails', '~> 7.0.8.7'
+ gem 'rails', '~> 7.1.5.1'
$ bundle update
Rails 7.1 への移行で発生した問題とその解決策
プロジェクトで Rails 7.0.8.7 から 7.1.5.1 へのバージョンアップを実施した際に、いくつかの問題が発生しました。主に、既存の設定や依存関係との互換性の問題が見られました。以下に、発生した問題とそれに対する解決策をまとめます。
composite_primary_keys
gemの非対応
1. 発生した問題
composite_primary_keys gemがRails 7.1 に未対応で使えなくなりました。
参考:Is gem still relevant with Rails 7.1?
~/g/g/U/herokura (*´ω`*) < bundle update rails 19:59:11
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
Could not find compatible versions
Because composite_primary_keys >= 14.0.1, < 14.0.4 depends on activerecord ~> 7.0.0
and composite_primary_keys >= 14.0, < 14.0.1 could not be found in rubygems repository https://rubygems.org/ or installed locally,
composite_primary_keys >= 14.0, < 14.0.4 requires activerecord ~> 7.0.0.
And because composite_primary_keys >= 14.0.4 depends on activerecord ~> 7.0.2
and rails >= 7.1.5.1, < 7.2.0.beta1 depends on activerecord = 7.1.5.1,
composite_primary_keys >= 14.0 is incompatible with rails >= 7.1.5.1, < 7.2.0.beta1.
So, because Gemfile depends on rails ~> 7.1.5.1
and Gemfile depends on composite_primary_keys ~> 14.0,
version solving has failed.
しかしRails 7.1では、ネイティブで複合主キーがサポートされるようになったため、composite_primary_keys
gemは不要になりました。
解決策
-
composite_primary_keys
gemを削除。 -
self.primary_keys
をself.primary_key
に変更。
- self.primary_keys = :first_name, :last_name
+ self.primary_key = [:first_name, :last_name]
2. foreign_key配列の非推奨
発生した問題
/Users/matsumoto_t/ghq/github.com/UUUM/herokura/vendor/bundle/ruby/3.2.0/gems/activerecord-
7.1.5.1/lib/active_record/reflection.rb:446:in `validate_reflection!': Passing [:process_id, :employee_account_code]
array to :foreign_key option on the Organization::ImportEmployee#import_depart
ment_employees association is not supported. Use the query_constraints: [:process_id, :employee_account_code]
option instead to represent a composite foreign key. (ArgumentError)
raise ArgumentError, message
^^^^^^^^^^^^^^^^^^^^^^
解決策
has_many
やbelongs_to
で複合外部キーを使用する場合、foreign_key
ではなくquery_constraints
を使用するように変更。
- has_many :employees, foreign_key: [:process_id, :employee_account_code]
+ has_many :employees, query_constraints: [:process_id, :employee_account_code]
secret_key_base
の保存場所変更
3. Rails 7.1では、ローカル環境のsecret_key_base
の保存場所がcredentials
に移行しました。
発生した問題
下記エラーはDevise が Rails.application.secrets.secret_key_base
を参照している ため発生しました。
/Users/matsumoto_t/ghq/github.com/UUUM/herokura/vendor/bundle/ruby/3.2.0/gems/devise-
4.9.4/lib/devise/secret_key_finder.rb:12:in `find': DEPRECATION WARNING: `Rails.application.secrets` is deprecated in favor of
`Rails.application.credentials` and will be removed in Rails 7.2. (called
from <main> at /Users/matsumoto_t/ghq/github.com/UUUM/herokura/config/environment.rb:5)
(ActiveSupport::DeprecationException)
解決策
Rails.application.secrets.secret_key_base
をRails.application.secret_key_base
に変更。
Devise.setup do |config|
+ config.secret_key = Rails.application.secret_key_base
end
4. Enumの属性定義
発生した問題
Rails 7.1では、 Enum
を使用する場合、属性がデータベースに存在しない場合には、明示的に attribute
を定義する必要があります。
Undeclared attribute type for enum 'stagename_options' in Sample. Enums must be backed
by a database column or declared
with an explicit type via `attribute`. (RuntimeError)
解決策
以下のようにattribute
を追加してからenum
を定義。
+ attribute :stagename_options, :string
enum :stagename_options, { 'TestStage1' => 'TestStage1', 'TestStage2' => 'TestStage2', 'TestStage3' => 'TestStage3' }
5. Zeitwerkとrequireの競合
発生した問題
テスト時にrequire
とZeitwerkのオートローディングが競合してエラーが発生しました。
<internal:/Users/matsumoto_t/.rbenv/versions/3.2.6/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38
:in `require': cannot load such file -- example_module/order_type (LoadError)
Zeitwerk は autoload_paths
に含まれるディレクトリのファイルを自動で読み込む仕組みを持っています。
そのため、通常は require
を使わなくても、ファイルが適切な場所にあれば自動的にロードされます。
解決策
Zeitwerkが自動でファイルをロードするため、明示的なrequire
は削除。
require 'test_helper'
- require 'example_module/order_type'
6. ActionController::Parametersのキー制限
発生した問題
Rails 7.1では、ActionController::Parameters
のキーにString
やSymbol
以外を使用できなくなりました。
ActionController::InvalidParameterKey:
all keys must be Strings or Symbols, got: Integer
解決策
ActionController::Parameters
のキーに使用する値がString
またはSymbol
になるよう修正。
参考:Only allow String and Symbol keys in ActionController::Parameters
7. table_nameの代替
発生した問題
Rails 7.1 でArel::Table
からtable_name
メソッドが削除されました。
NoMethodError: undefined method `table_name' for #<Arel::Table:0x00000001525d6e18
解決策
table_name
メソッドをname属性に置換。
参考:Drop unused table_name alias from Arel::Table
8. ActiveSupport::Loggerのbroadcastメソッド削除(sidekiq内部のエラー)
発生した問題
Sidekiq
内でbroadcast
メソッドが削除され、エラーが発生しました。
~/g/g/U/herokura 。+゚(∩´﹏'∩)゚+。 < bundle exec sidekiq -C config/sidekiq.yml
WARN: NoMethodError: undefined method `broadcast' for ActiveSupport::Logger:Class
解決策
Sidekiq
を 6.5 から 7.2.2 にアップデートで解決。
参考:Logger.broadcast removed from ActiveSupport causing sidekiq to break
9. ActiveSupport::Loggerのbroadcastメソッド削除(アプリケーションのlogger設定箇所のエラー)
発生した問題
ActiveSupport::Logger
からbroadcast
メソッドが削除されたためlogger設定箇所でエラーになりました。
WARN: NoMethodError: undefined method `broadcast' for ActiveSupport::Logger:Class
解決策
代わりにBroadcastLogger
クラスが追加されたためそれを適応。
def logger
@logger ||= Rails.logger.dup.tap do |logger|
- logger.extend(
- ActiveSupport::Logger.broadcast(
- ActiveSupport::Logger.new($stdout)
- )
+ # ブロードキャスト用のロガーを生成
+ broadcast_logger = ActiveSupport::BroadcastLogger.new(
+ ActiveSupport::Logger.new($stdout)
)
+ # ロガーにブロードキャスト用のロガーを設定
+ logger.instance_variable_set(:@broadcast_logger, broadcast_logger)
end
end
参考:Add a public API for broadcasting logs
10. clear_active_connections!の非推奨化
発生した問題
ActiveRecord::Base.clear_active_connections!
が非推奨されました。
~/g/g/U/herokura 。+゚(∩´﹏'∩)゚+。 < bundle exec sidekiq -C config/sidekiq.yml
WARN: ActiveSupport::DeprecationException: DEPRECATION WARNING: Calling `ActiveRecord::Base.clear_active_connections! is deprecated. Please call the method directly on the connection handler; for example: `ActiveRecord::Base.connection_handle
r.clear_active_connections!`. (called from block (2 levels) in <main> at /Users/matsumoto_t/ghq/github.com/UUUM/herokura/config/initializers/sidekiq.rb:6)
WARN: config/initializers/sidekiq.rb:6:in `block (2 levels) in <main>'
DEPRECATION WARNING: Calling `ActiveRecord::Base.clear_active_connections! is deprecated. Please call the method directly on the connection handler; for example: `ActiveRecord::Base.connection_handler.clear_active_connections!`. (called from block (2 levels) in <main> at /Users/matsumo
to_t/ghq/github.com/UUUM/herokura/config/initializers/sidekiq.rb:6)
解決策
ActiveRecord::Base.connection_handler.clear_active_connections!
に変更。
- ActiveRecord::Base.clear_active_connections!
+ ActiveRecord::Base.connection_handler.clear_active_connections!
Discussion