Ruby on Rails 8の主要な新機能・機能追加・変更点

## はじめに

Rubyを使用したOSSのWebアプリケーションフレームワーク、Ruby on Rails（以下Rails）の最新バージョンである8.0（以下Rails 8）が[2024年11月7日にリリースされました](https://rubyonrails.org/2024/11/7/rails-8-no-paas-required)。

Rails 8は、Kamal 2とThruster、Solid Cable/Solid Cache/Solid Queue（Solidアダプター）などの新機能が追加され、主にこれまでPaas（platform-as-a-service）で提供されてきた各種サービスを、Railsのフレームワークの機能である程度置き換えることができるような、メジャーバージョンアップグレードにふさわしい強力なリリースとなっています。

本記事では、[Railsの公式ブログ](https://rubyonrails.org/blog/)や[Railsガイド](https://guides.rubyonrails.org/v8.0/)、GitHubのRailsプロジェクトの[Issues](https://github.com/rails/rails/issues)や[Pull Requests](https://github.com/rails/rails/pulls)の内容をもとに、Rails 8の主要な機能追加・変更点の紹介を行います。

※ 以前のバージョンのRailsの主要な新機能・機能追加・変更点については以下を参照してください。

* [Ruby on Rails 7.2の主要な新機能・機能追加・変更点](https://qiita.com/ryohashimoto/items/08f05bc0ae2f1315a442)
* [Ruby on Rails 7.1の主要な新機能・機能追加・変更点](https://qiita.com/ryohashimoto/items/ed669f2e529d489e9fe4)
* [Ruby on Rails 7の主要な新機能・機能追加・変更点](https://qiita.com/ryohashimoto/items/f5382478c78f296d8291)

## 注意点

### Rubyのバージョン

Rails 8を動かすには、Ruby 3.2以上が必要になります。

### Railsのサポート対象のバージョン

Rails 8のリリース前に[メインテナンスポリシー](https://rubyonrails.org/maintenance)が更新されました。
大きな変更点は以下の通りです。
* 今後は6ヶ月おきに新しいマイナーバージョンがリリースされるようになる。
  * Rails 8.0が2024年11月にリリースされたので、Rails 8.1は2025年5月頃にリリースされる予定
* 各マイナーバージョンはリリースから1年間、バグ修正が行われる。
* 各マイナーバージョンはリリースから2年間、セキュリティ問題の修正が行われる。

執筆時点でサポートされている過去のRailsのバージョンは以下の通りです。
（バージョン6系列のサポートは終了しています。）

#### バグ修正

* 7.2.x: 2025年8月9日まで

#### セキュリティ問題の修正

* 7.2.x: 2026年8月9日まで
* 7.1.x: 2025年10月1日まで
* 7.0.x: 2025年4月1日まで

**参考**

* [Ruby on Rails — Maintenance policy](https://rubyonrails.org/maintenance)

## 新機能

### Kamal（Dockerコンテナのデプロイツール）

[Kamal](https://kamal-deploy.org/)というDockerコンテナを本番環境に簡単にデプロイするツールが同梱されるようになりました。

SSHでログイン可能なDockerホスト（クラウドの仮想マシンやローカルマシンなど）とDockerイメージを保存したレジストリ（DockerHubやGitHubなど）をあらかじめ用意しておき、`kamal setup`を実行するだけで、本番環境へのデプロイが可能になります。また、`kamal console`コマンドでRailsコンソールを実行することもできるようになります。

これまでRailsアプリケーションのデプロイで使用されていたCapistranoをコンテナ用に置き換えたツールと考えるのが分かりやすいでしょう。また、AWSやGCPなどの各種クラウドのデプロイツールよりも簡単に使用できるようです。

**参考**

* [Kamal — Deploy web apps anywhere](https://kamal-deploy.org/)

### Thruster（HTTP/2 プロキシサーバー）

RailsアプリケーションのDockerファイルに、Thrusterと呼ばれるプロキシサーバーの設定が含まれ、Pumaの前段に配置するようになりました。これにより、Nginxなど別のWebサーバーを用意する必要がなくなっています。
Thrusterには以下の機能が含まれています。

* HTTP/2のサポート
* Let's Encryptによる自動化されたTLS証明書の管理
* 公開アセット（JavaScript、CSS、画像など）のHTTPキャッシュ
* X-Sendfileのサポートと圧縮

**参考**

* [basecamp/thruster](https://github.com/basecamp/thruster)

### Solid Cable

DBを使用したAction CableのアダプタであるSolid Cableが含まれるようになりました。Solid CableによってRedisを使用せずにWebSocketを使用したリアルタイム機能を使用することができるようになります。内部的にはRedisのpub/subの代わりにDBへのポーリングを使用しており、RDBMSとしては、SQLite3の他にPostgreSQLやMySQLもサポートしています。（他のSolidアダプターも同様）

以下のように設定ファイル（本番環境の部分を抜粋）では接続先のDBやポーリングの間隔、メッセージの保持期間を設定することができます。パフォーマンスを改善する場合は、アプリケーションの他とは別のDBインスタンスを使用し、ポーリングの間隔を実用上問題のない数値に長くするとよいでしょう。

```yaml
production:
  adapter: solid_cable
  connects_to:
    database:
      writing: cable # 接続先のDB
  polling_interval: 0.1.seconds # ポーリングの間隔
  message_retention: 1.day # メッセージの保持期間
```

詳細に関しては以下のプロジェクトのページを参考にしてください。

**参考**

* [GitHub - rails/solid_cable: A database backed ActionCable adapter](https://github.com/rails/solid_cable)

### Solid Cache

DBを使用したActive SupportのキャッシュストアであるSolid Cacheが含まれるようになりました。
Solid Cacheによってメモリを使用したRedisやMemcachedよりも長期間にわたって大容量のアプリケーションのデータのキャッシュを行うことができるようになります。
現在はSSDのアクセス速度が速くなっているので、実用上はメモリを使用すると比較して問題はないとのことです。こちらも、RDBMSとしては、SQLite3の他にPostgreSQLやMySQLもサポートしています。

以下のように設定ファイル（本番環境の部分を抜粋）では接続先のDBやオプションを設定することができます。この例では複数のDBに分けてキャッシュを保存し、オプションとして、最大キャッシュ期間を60日、最大容量を256ギガバイトとし、名前空間をRailsの環境名（production）にしています。

```yaml
production:
  databases: [production_cache1, production_cache2]
  store_options:
    max_size: <%= 256.gigabytes %>
    max_age: <%= 60.days.to_i %>
    namespace: <%= Rails.env %>
```

**参考**

* [GitHub - rails/solid_cache: A database-backed ActiveSupport::Cache::Store](https://github.com/rails/solid_cache)

### Solid Queue

DBを使用したActive JobのバックエンドであるSolid Queueが含まれるようになりました。
Solid Queueは、Redisを使用したSidekiqやResqueといったジョブ実行システムと同様に、単純なジョブのエンキューや実行だけでなく、遅延実行、同期処理の制御、定期（繰り返し）実行、キューの停止、優先順序づけなど本格的な実用に耐えるものとなっています。
こちらも、RDBMSとしては、SQLite3の他にPostgreSQLやMySQLもサポートしており、SQL文の`FOR UPDATE SKIP LOCKED`を使用することで、ジョブをpollingする際のブロッキングやロック解除待ちといったパフォーマンスを劣化させる要因を回避しています。

Solid Queueでは、以下の4種類のアクター（Actor）がプロセスとして実行されています。（英語で複数形になっているものは複数実行され、Theがついているものは1つのみ実行）

* ワーカー（Workers）
  * キューからジョブを取り出し実行を行う。
    * `solid_queue_ready_executions`テーブルに登録されたジョブに対して操作を行う。
* ディスパッチャー（Dispatchers）
  * スケジューリングされたジョブを選択し、ワーカーが実行できるようにする
    * `solid_queue_scheduled_executions`テーブルから`solid_queue_ready_executions`テーブルにジョブを移動する。
* スケジューラー（The scheduler）
  * 定期（繰り返し）実行の際にジョブをエンキューする。
* スーパーバイザー（The supervisor）
  * ワーカーとディスパッチャーを設定に基づいて実行し、動作状況をハートビートで監視し、必要に応じて停止と起動を行う。

設定ファイルでは以下のように、ジョブをチェックする間隔やプロセス数、スレッド数などを指定することができます。

```yaml
production:
  dispatchers:
    - polling_interval: 1 # ジョブをチェックする間隔（ポーリング間隔、秒）
      batch_size: 500 # ジョブを1度にワーカーに渡す数
      concurrency_maintenance_interval: 300 # ブロックされたジョブをチェックする間隔（秒）
  workers:
    - queues: "*"
      threads: 3 # 1プロセスで実行するスレッドの数
      polling_interval: 2
    - queues: [ real_time, background ] # realtime, backgroundキューは上記の値を上書き
      threads: 5 # 1プロセスで実行するスレッドの数
      polling_interval: 0.1
      processes: 3 # プロセス数
```

**参考**

* [GitHub - rails/solid_queue: Database-backed Active Job backend](https://github.com/rails/solid_queue)

## 機能追加

### 認証機能を生成できるように

`bin/rails generate authentication`で認証機能を生成できるようになりました。これらはRails 5で導入された`has_secure_password`やRails 7.1で導入された`authenticate_by`を拡張したもので、以下のコードを生成します。

* `Session`モデル
  * ユーザーID、トークン、IPアドレス、User-Agentなどセッションに関する情報
* `User`モデル
  * メールアドレス、ダイジェスト化されたパスワードなどユーザーに関する情報
* `PasswordsController`とviewファイル、`PasswordsMailer`
  * パスワードリセットの機能
* `SessionsController`とviewファイル
  * ログイン、ログアウトの機能
* `Authentication` concern
  * セッションの情報を元に、ログインに関するメソッドをコントローラに提供するモジュール
* 上記に関連したマイグレーションファイル

Deviseなど外部のライブラリを使用しなくても、簡単なパスワードログイン機能をRailsだけで実現できるようになるので、便利に使用できそうです。

**参考**

* [Rails 8 introduces a basic authentication generator - BigBinary Blog](https://www.bigbinary.com/blog/rails-8-introduces-a-basic-authentication-generator)


## 変更点

### Redisへの依存の削除

新機能の欄で紹介したSolidアダプターの導入に伴い、Redisを使用する必要がなくなったので、Gemfileからもredisに関連するライブラリが削除されています。

### SQLiteを本番環境でも使えるように

Rails本体と、sqlite3-rubyライブラリに各種の修正が行われたことで、SQLiteを本番環境でも使えるようになりました。（すでに37signalsのCampfireやWritebookなどの各種サービスはSQLiteで運用されているそうです。）

**参考**

[Pull requests author:fractaledmind · rails/rails](https://github.com/rails/rails/pulls?q=is%3Apr+author%3Afractaledmind)
[Open & writable database connections carried across fork() are automatically discarded in the child by flavorjones · Pull Request #558 · sparklemotion/sqlite3-ruby](https://github.com/sparklemotion/SQLite3-ruby/pull/558)

### PropshaftでSprocketsを置き換え

Rails 8で新しく生成されたアプリケーションのアセットパイプラインが、これまで長い間使用されていたSprocketsからPropshaftに変更されました。Propshaftはアセットのロードパスの設定と、Digestの付与、開発用のサーバーといった単純な機能に絞ることで、実装としてはよりシンプルで高速に動作します。

**参考**

[rails/propshaft: Deliver assets for Rails](https://github.com/rails/propshaft)