rails7へのバージョンアップを安全に行うために使用するnew_framework_defaults_7_0.rbの各項目をさらっと解説

# new_framework_defaults_7_0.rbとは

railsバージョンアップの工程で、`rails app:update`コマンドを実行すると、`config/initializers/new_framework_defaults_7_0.rb`と言うファイルが作成されます。
このファイルにはrails6.1から7.0へのバージョンアップにおいて変更されるアプリケーションの設定値が書かれています。
設定値毎にコメントアウトを外していくとその箇所だけ新しい設定に変更できるので、部分的に変更を行うことが可能です。

# 使い方

**1. `config/application.rb`で`config.load_defaults`を`6.1`に指定しておく**

railsのgem自体は7.0をインストールしておきますが、`config.load_defaults`を`6.1`に指定しておくことで設定は6.1の値を読み込む様にしておきます。

**2. `config/initializers/new_framework_defaults_7_0.rb`のコメントアウトを外していきアプリケーションに影響がないか確認する**

**3. すべての項目が有効にできたら`config/application.rb`で`config.load_defaults`を`7.0`にして、`config/initializers/new_framework_defaults_7_0.rb`を削除**

互換性を保つ必要があり設定を変更する場合は`config/application.rb`で`config.load_defaults`に`7.0`を指定した上で、変更したい設定のみを`config/application.rb`などに個別に定義して、`config/initializers/new_framework_defaults_7_0.rb`を削除します。

# 項目の説明

`config/initializers/new_framework_defaults_7_0.rb`では以下の19の設定値が設定可能です。
以後はそれぞれの内容と値について解説していきます。

```
* Rails.application.config.action_view.button_to_generates_button_tag
* Rails.application.config.action_view.apply_stylesheet_media_default = false
* Rails.application.config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA256
* Rails.application.config.active_support.hash_digest_class = OpenSSL::Digest::SHA256
* Rails.application.config.active_support.remove_deprecated_time_with_zone_name = true
* Rails.application.config.active_support.cache_format_version = 7.0
* Rails.application.config.active_support.executor_around_test_case = true
* Rails.application.config.active_support.isolation_level = :thread
* Rails.application.config.action_mailer.smtp_timeout = 5
* Rails.application.config.active_storage.video_preview_arguments =　"-vf 'select=eq(n\\,0)+eq(key\\,1)+gt(scene\\,0.015),loop=loop=-1:size=2,trim=start_frame=1' -frames:v 1 -f image2"
* Rails.application.config.active_record.automatic_scope_inversing = true
* Rails.application.config.active_record.verify_foreign_keys_for_fixtures = true
* Rails.application.config.active_record.partial_inserts = false
* Rails.application.config.action_controller.raise_on_open_redirects = true
* Rails.application.config.active_storage.variant_processor = :vips
* Rails.application.config.action_dispatch.cookies_serializer = :hybrid
* Rails.application.config.action_controller.wrap_parameters_by_default = true
* Rails.application.config.active_support.use_rfc4122_namespaced_uuids = true
* Rails.application.config.action_dispatch.default_headers = {
  "X-Frame-Options" => "SAMEORIGIN",
  "X-XSS-Protection" => "0",
  "X-Content-Type-Options" => "nosniff",
  "X-Download-Options" => "noopen",
  "X-Permitted-Cross-Domain-Policies" => "none",
  "Referrer-Policy" => "strict-origin-when-cross-origin"
}
```


## Rails.application.config.action_view.button_to_generates_button_tag = true

`button_to`メソッドを使ったときにHTMLが`<input type="submit"`だったのが`<button type="submit">`に変更されました。
既存の設定を維持したい場合は`false`を設定します。

変更されたPR: https://github.com/rails/rails/pull/40747

## Rails.application.config.action_view.apply_stylesheet_media_default = false

`stylesheet_link_tag`メソッドでスタイルシートを読み込んだ場合に`media`属性を指定しなかった場合は`media="screen"`が指定されたHTMLを生成します。
しかし、ブラウザのデフォルトではmediaを指定しなかった場合は`media="all"`の振る舞いをするので、ブラウザのデフォルトに合わせて`stylesheet_link_tag`で`media`属性を指定しなかった場合は`media`何も指定しないHTMLを出力します。

```ruby
# Before
> stylesheet_link_tag "style"
=> <link href="/assets/style.css" media="screen" rel="stylesheet" />

# After
> stylesheet_link_tag "style"
=> <link href="/assets/style.css" rel="stylesheet" />
```

既存の設定を維持したい場合は`true`を指定します。

変更されたPR: https://github.com/rails/rails/pull/41215

## Rails.application.config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA256
rails guideに説明が書かれていたので引用します。

> キージェネレータで用いられるデフォルトのダイジェストクラスが、SHA1からSHA256に変更されました。 その結果、Railsで生成されるあらゆる暗号化メッセージがこの影響を受けるようになり、暗号化cookieも同様に影響を受けます。

rails guide: https://railsguides.jp/upgrading_ruby_on_rails.html#rails-6-1%E3%81%8B%E3%82%89rails-7-0%E3%81%B8%E3%81%AE%E3%82%A2%E3%83%83%E3%83%97%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%89

既存の設定を維持したい場合は`OpenSSL::Digest::SHA1`を指定します。 

変更されたPR: https://github.com/rails/rails/pull/40770

## Rails.application.config.active_support.hash_digest_class = OpenSSL::Digest::SHA256

アプリケーションのデフォルトのダイジェストクラスがSHA1からSHA256に変更されました。
この変更により、たとえばEtagsが変更されてキャッシュが無効化される影響があります。

既存の設定を維持したい場合は`OpenSSL::Digest::SHA1`を指定します。 

変更されたPR: https://github.com/rails/rails/pull/41043

## Rails.application.config.active_support.remove_deprecated_time_with_zone_name = true

`ActiveSupport::TimeWithZone.name` がrailsでオーバーライドされており`Time`を固定値で返却していましたが混乱の元になるので`name`メソッドのオーバーライドを止めてruby実装の`Class.name`を呼び出すようにします。

既存の設定を維持したい場合は`false`を指定します。 

変更されたPR: https://github.com/rails/rails/pull/41835 , https://github.com/rails/rails/commit/3457a4676d91836ac3dfd6765f069eee752c598c

## Rails.application.config.active_support.cache_format_version = 7.0

`ActiveSupport::Cache`のシリアライザのパフォーマンス改善です。

`6.1`を指定した際の旧方式のキャッシュを`7.0`指定時に読み込むことができるが、反対に`7.0`を指定した際の新方式のキャッシュは`6.1`指定時に読み込むことがでないので、バージョンアップのロールバックをした際にエラーになってしまいます。
`6.1`を指定してリリースを行い安定したら`7.0`に変更すると安全です。

変更されたPR: https://github.com/rails/rails/pull/42025

## Rails.application.config.active_support.executor_around_test_case = true

テスト実行を実際のリクエストやジョブに近づけるために、テスト実行毎に`Rails.application.executor.wrap`を呼び出しグローバルなデータをクリーンアップします。
これによりActive Recordクエリキャッシュや非同期クエリなどのこれまでのテストでは動かなかった内部の挙動が実行されるようになります。

既存の設定を維持したい場合は`false`を指定します。 

変更されたPR: https://github.com/rails/rails/pull/43550

## Rails.application.config.active_support.isolation_level = :thread

ActiveSupportでローカルスレッド変数を扱う際の分離レベルが設定可能になりました。
ActiveSupportではローカルスレッド変数を扱う場合多くの箇所で`Thread.current#[]`を使用していましたが、この変数は異なるfiber間で変数を共有できない為、例えば`falcon`などfiberベースのwebサーバーを使用している場合に問題が発生するケースが報告されていました。
そのため、ローカルスレッド変数分離レベルはアプリケーション構成によって設定が変更できるようになりました。

`falcon`を使用している場合は`:fiber`を、
`puma` / `sidekiq`を使用している場合は`:thread`を指定します。
`unicorn`, `resque`はスレッドベース、プロセスベースどちらでも実行可能です。実行する場合は`:thread`を指定します。

変更されたPR: https://github.com/rails/rails/pull/43596

## Rails.application.config.action_mailer.smtp_timeout = 5

ActionMailerでSMTPの`:open_timeout`と`:read_timeout`にdefaultで5秒が指定されます。

変更されたPR: https://github.com/rails/rails/pull/41248 , https://github.com/rails/rails/commit/52db7f2ef3c4a902227cac163657c89282986e25

## Rails.application.config.active_storage.video_preview_arguments = "-vf 'select=eq(n\\,0)+eq(key\\,1)+gt(scene\\,0.015),loop=loop=-1:size=2,trim=start_frame=1' -frames:v 1 -f image2"

ActiveStorageビデオプレビュー画像を生成する`ffmpeg`への設定が可能になりました。
`FFmpeg` v3.4以上では、デフォルトの画像ではなく、シーン検出を指定してプレビュー画像を表示できるようになりました。
デフォルトの値は`"-y -vframes 1 -f image2"`です。

https://guides.rubyonrails.org/v7.0/upgrading_ruby_on_rails.html#active-storage-video-preview-image-generation

変更されたPR: https://github.com/rails/rails/pull/42471

## Rails.application.config.active_record.automatic_scope_inversing = true

オプションでscopeを指定したアソシエーション定義でも自動で関連付けを推測するようになったので`inverse_of`を明示する必要がなくなりました。

```diff
class Post < ActiveRecord::Base
  has_many :comments, -> { visible }
end

class Comment < ActiveRecord::Bas
-  belongs_to :post, inverse_of :: post
+  belongs_to :post
end
```

既存の設定を維持したい場合は`false`を指定します。 

変更されたPR: https://github.com/rails/rails/pull/43358

## Rails.application.config.active_record.verify_foreign_keys_for_fixtures = true

fixtureで外部キー制約に違反している存在する場合にテスト実行を失敗させます。
この機能はPostgreSQL, SQLiteでのみ有効です。

変更されたPR: https://github.com/rails/rails/pull/42674

## Rails.application.config.active_record.partial_inserts = false

insert文を発行する時に、デフォルト値が指定されているカラムでデフォルト値と同一の値を入力するかどうかを指定します。
デフォルトは`false`でデフォルト値が指定されているカラムに差分がなくても値の指定を行います。

変更されたPR: https://github.com/rails/rails/pull/42355

## Rails.application.config.action_controller.raise_on_open_redirects = true

オープンリダイレクトが発生した場合に例外を発生させる様になりました。
`redirect_to`で任意のURLにリダイレクトする際、`allow_other_host`オプションで許可する外部のホストを指定する必要があります。
このオプションに指定されていないURLにリダイレクトする処理が実行された場合に例外を発生します。

変更されたコミット: https://github.com/rails/rails/commit/5e93cff83599833380b4cb3d99c020b5efc7dd96

## Rails.application.config.active_storage.variant_processor = :vips

ActiveStorageでデフォルトのvariant processor が`mini_magick`/`ImageMagick`から、`image_processing`/`libvips`に変更されました。
`ImageMagick`と比べた`vips`の優位性としてメモリ使用率、処理速度、セキュリティー脆弱性の少なさが挙がっています。
`mini_magick`から`vips`への移行は以下のページを参照との事。
https://gist.github.com/brenogazzola/a4369965a1da426d50f11d080fe2e563

`mini_magick`を使用し続ける場合は値に`:mini_magick`を指定します。

変更されたPR: https://github.com/rails/rails/pull/42744

## Rails.application.config.action_dispatch.cookies_serializer = :hybrid 

railsデフォルトの設定が`:marshal`から`:json`に変更されます。

バージョン`4.1`以降のrailsアプリではデフォルトで`:marshal`が定義され`rails new`時に作成される`config/initializers/cookies_serializer.rb`によって`action_dispatch.cookies_serializer`が`:json`に上書きされていました。
背景としては、過去rails`4.0`から`4.1`へのバージョンアップの際に、互換性を維持する為デフォルトの設定は変更せず、新しく作るアプリケーションのみ変更するために`config/initializers/cookies_serializer.rb`で上書きしてた為です。

rails7になりinitializersファイルを減らすため、デフォルト値が`:json`に変更され`config/initializers/cookies_serializer.rb`は不要になりました。
`:hybrid`では、`marshal`, `json`形式のcookie読み込みが可能で書き込みは`json`形式になる為シリアライザの移行が容易になります。

既存の設定を維持したい場合は`:marshal`を指定します。

変更されたPR: https://github.com/rails/rails/pull/42538

## Rails.application.config.action_controller.wrap_parameters_by_default = true

これまでは`rails new`時に`config/initializers/wrap_parameters.rb`が作成されこのファイルの中で行われていたwrap_parametersの仕組みがデフォルトの設定に移行されました。
initializersの設定を以下の通りにしていた場合、またはアプリケーション固有の定義をしていた場合は`true`を指定することで同じ値が設定されます。

```ruby:onfig/initializers/wrap_parameters.rb
ActiveSupport.on_load(:action_controller) do
  wrap_parameters format: [:json]
end
```

wrap_parametersを使用しない場合は`false`を指定します。

`wrap_parameters`については[こちらの記事](https://qiita.com/SoarTec-lab/items/a885e8f473ecab7748c7)でも解説しています。

変更されたPR: https://github.com/rails/rails/pull/43237

## Rails.application.config.active_support.use_rfc4122_namespaced_uuids = true

`Digest::UUID.uuid_v3` / `Digest::UUID.uuid_v5`メソッドの引数で指定する名前空間の形式には、RFC4122に準拠しているUUIDである事を強制する様になりました。
引数で指定する名前空間IDにUUID以外の値を指定した場合は`ArgumentError`が発生するようになります。

https://guides.rubyonrails.org/configuring.html#config-active-support-use-rfc4122-namespaced-uuids

既存の設定を維持したい場合は`false`を指定します。 

変更されたPR: https://github.com/rails/rails/pull/37682

## Rails.application.config.action_dispatch.default_headers = {
  "X-Frame-Options" => "SAMEORIGIN",
  "X-XSS-Protection" => "0",
  "X-Content-Type-Options" => "nosniff",
  "X-Download-Options" => "noopen",
  "X-Permitted-Cross-Domain-Policies" => "none",
  "Referrer-Policy" => "strict-origin-when-cross-origin"
}


`X-XSS-Protection`ヘッダーの使用が非推奨になったので`'0'`を指定することでヘッダーの使用を廃止するようにしました。
rails7.0以前は`'1; mode=block'`が指定されていました。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection

変更されたPR: https://github.com/rails/rails/pull/41769

# `config/initializers/new_framework_defaults_7_0.rb`ファイル全体

```ruby:config/initializers/new_framework_defaults_7_0.rb
# Be sure to restart your server when you modify this file.
#
# This file eases your Rails 7.0 framework defaults upgrade.
#
# Uncomment each configuration one by one to switch to the new default.
# Once your application is ready to run with all new defaults, you can remove
# this file and set the `config.load_defaults` to `7.0`.
#
# Read the Guide for Upgrading Ruby on Rails for more info on each option.
# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html

# `button_to` view helper will render `<button>` element, regardless of whether
# or not the content is passed as the first argument or as a block.
# Rails.application.config.action_view.button_to_generates_button_tag = true

# `stylesheet_link_tag` view helper will not render the media attribute by default.
# Rails.application.config.action_view.apply_stylesheet_media_default = false

# Change the digest class for the key generators to `OpenSSL::Digest::SHA256`.
# Changing this default means invalidate all encrypted messages generated by
# your application and, all the encrypted cookies. Only change this after you
# rotated all the messages using the key rotator.
#
# See upgrading guide for more information on how to build a rotator.
# https://guides.rubyonrails.org/v7.0/upgrading_ruby_on_rails.html
# Rails.application.config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA256

# Change the digest class for ActiveSupport::Digest.
# Changing this default means that for example Etags change and
# various cache keys leading to cache invalidation.
# Rails.application.config.active_support.hash_digest_class = OpenSSL::Digest::SHA256

# Don't override ActiveSupport::TimeWithZone.name and use the default Ruby
# implementation.
# Rails.application.config.active_support.remove_deprecated_time_with_zone_name = true

# Change the format of the cache entry.
# Changing this default means that all new cache entries added to the cache
# will have a different format that is not supported by Rails 6.1 applications.
# Only change this value after your application is fully deployed to Rails 7.0
# and you have no plans to rollback.
# Rails.application.config.active_support.cache_format_version = 7.0

# Calls `Rails.application.executor.wrap` around test cases.
# This makes test cases behave closer to an actual request or job.
# Several features that are normally disabled in test, such as Active Record query cache
# and asynchronous queries will then be enabled.
# Rails.application.config.active_support.executor_around_test_case = true

# Define the isolation level of most of Rails internal state.
# If you use a fiber based server or job processor, you should set it to `:fiber`.
# Otherwise the default of `:thread` if preferable.
# Rails.application.config.active_support.isolation_level = :thread

# Set both the `:open_timeout` and `:read_timeout` values for `:smtp` delivery method.
# Rails.application.config.action_mailer.smtp_timeout = 5

# The ActiveStorage video previewer will now use scene change detection to generate
# better preview images (rather than the previous default of using the first frame
# of the video).
# Rails.application.config.active_storage.video_preview_arguments =
#   "-vf 'select=eq(n\\,0)+eq(key\\,1)+gt(scene\\,0.015),loop=loop=-1:size=2,trim=start_frame=1' -frames:v 1 -f image2"

# Automatically infer `inverse_of` for associations with a scope.
# Rails.application.config.active_record.automatic_scope_inversing = true

# Raise when running tests if fixtures contained foreign key violations
# Rails.application.config.active_record.verify_foreign_keys_for_fixtures = true

# Disable partial inserts.
# This default means that all columns will be referenced in INSERT queries
# regardless of whether they have a default or not.
# Rails.application.config.active_record.partial_inserts = false
#
# Protect from open redirect attacks in `redirect_back_or_to` and `redirect_to`.
# Rails.application.config.action_controller.raise_on_open_redirects = true

# Change the variant processor for Active Storage.
# Changing this default means updating all places in your code that
# generate variants to use image processing macros and ruby-vips
# operations. See the upgrading guide for detail on the changes required.
# The `:mini_magick` option is not deprecated; it's fine to keep using it.
# Rails.application.config.active_storage.variant_processor = :vips

# If you're upgrading and haven't set `cookies_serializer` previously, your cookie serializer
# was `:marshal`. Convert all cookies to JSON, using the `:hybrid` formatter.
#
# If you're confident all your cookies are JSON formatted, you can switch to the `:json` formatter.
#
# Continue to use `:marshal` for backward-compatibility with old cookies.
#
# If you have configured the serializer elsewhere, you can remove this.
#
# See https://guides.rubyonrails.org/action_controller_overview.html#cookies for more information.
# Rails.application.config.action_dispatch.cookies_serializer = :hybrid

# Enable parameter wrapping for JSON.
# Previously this was set in an initializer. It's fine to keep using that initializer if you've customized it.
# To disable parameter wrapping entirely, set this config to `false`.
# Rails.application.config.action_controller.wrap_parameters_by_default = true

# Specifies whether generated namespaced UUIDs follow the RFC 4122 standard for namespace IDs provided as a
# `String` to `Digest::UUID.uuid_v3` or `Digest::UUID.uuid_v5` method calls.
#
# See https://guides.rubyonrails.org/configuring.html#config-active-support-use-rfc4122-namespaced-uuids for
# more information.
# Rails.application.config.active_support.use_rfc4122_namespaced_uuids = true

# Change the default headers to disable browsers' flawed legacy XSS protection.
# Rails.application.config.action_dispatch.default_headers = {
#   "X-Frame-Options" => "SAMEORIGIN",
#   "X-XSS-Protection" => "0",
#   "X-Content-Type-Options" => "nosniff",
#   "X-Download-Options" => "noopen",
#   "X-Permitted-Cross-Domain-Policies" => "none",
#   "Referrer-Policy" => "strict-origin-when-cross-origin"
# }
```