Rails 7.1 リリースノートについてまとめたものを備忘録として残しておく
他バージョンのリリースノートまとめ
Rails 7.1 系での新機能および変更点
Dockerfileの生成
新規アプリケーションで Dockerfile が自動生成されるようになった
複合プライマリキーのサポート
複合プライマリキーがサポートされ、マイグレーションや、Active Record のクエリメソッドなど Rails のアプリケーション全般で使用できるようになった
DB に複合プライマリキーを使用したテーブルを作成するには、以下のようにマイグレーションの change_table の primary_key: オプションにカラム名の配列を渡す
class CreateBooks < ActiveRecord::Migration[7.1]
def change
create_table :books, primary_key: [:store_id, :sku] do |t|
t.integer :store_id
t.string :sku
t.string :name
t.text :description
end
end
end
使用例
クエリメソッド
Product.find([3, "XYZ12345"]) # store_id: 3, sku: "XYZ12345"を指定
Product.where(Product.primary_key => [[1, "ABC98765"], [7, "ZZZ11111"]]) # store_id: 3, sku: "XYZ12345"とstore_id: 7, sku: "ZZZ11111"
Product.first # SELECT * FROM products ORDER BY products.store_id ASC, products.sku ASC LIMIT 1
モデルの関連
従来の id ではなく、複合プライマリキーを使用するには、has_many や belongs_to などのオプションで query_constraints を使用する
class Author < ApplicationRecord
self.primary_key = [:first_name, :last_name]
has_many :books, query_constraints: [:first_name, :last_name]
end
class Book < ApplicationRecord
belongs_to :author, query_constraints: [:author_first_name, :author_last_name]
end
ActiveRecord::Base.normalizes によるモデルの属性の正規化
メールアドレスの小文字化、電話番号のハイフン削除などの正規化を、モデル内で行えるようになった
使用例
class User < ApplicationRecord
normalizes :email, with: -> email { email.downcase }
normalizes :tel, with: -> tel { tel.delete("-") }
end
上記の定義を行っている場合、以下のような正規化が行われる
user = User.new(email: 'SMITH@example.com', tel: '090-1234-5678')
=> #<User:0x0000000108142a68 id: nil, email: "smith@example.com", tel: "09012345678", created_at: nil, updated_at: nil>
Active Record の where
, exists?
に正規化前の値を渡すと正規化されて SQL が実行される
User.where(email: 'SMITH@example.com')
#=> User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? /* loading for pp */ LIMIT ? [["email", "smith@example.com"], ["LIMIT", 11]]
User.exists?(email: 'SMITH@example.com')
#=> User Exists? (0.3ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ? [["email", "smith@example.com"], ["LIMIT", 1]]
Active Record に非同期クエリのメソッドが追加
Active Recordに、以下の async_
で始まる各種の非同期クエリのメソッドが追加された
- async_count
- async_sum
- async_minimum
- async_maximum
- async_average
- async_pluck
- async_pick
- async_ids
- async_find_by_sql
- async_count_by_sql
使用例
メソッド呼出後に、クエリの実行状態を持つ ActiveRecord::Promise オブジェクトを返す
実行が完了している場合は、#value メソッドで値を取得することができる
promise = Book.where(published: true).async_count
promise.value
# => 5
Trilogy MySQL アダプタのサポート
trilogy は従来の mysql2 アダプタに比べて高速で軽量に動作する
使用例
development:
adapter: trilogy
database: blog_development
pool: 5
ジョブの一括エンキュー(perform_all_later)
複数のジョブを一括でエンキューする、 perform_all_later が ActiveJob のクラスメソッドとして追加された
このメソッドを使用することで、 Sidekiq など、Active Job のアダプタで enqueue_all メソッドを使用できるジョブ実行システムの場合では、個別にジョブをエンキューすることなく効率よくジョブを実行できるようになった。
※上記の場合 Active Job のエンキュー用のコールバックが実行されないことに注意
また、enqueue_all を使用できない場合は、ループで個別のジョブをエンキューを行う
ActiveSupport::MessagePack のサポート
Ruby オブジェクトをシリアライズする際に従来は JSON や Marshal のシリアライザを使用していた
今回のアップデートでより高速で、データが軽量になる msgpack gem を使用した ActiveSupport::MessagePackが利用できるようにようになった
Rails アプリケーションの各種設定でも、以下の例のように :message_pack が指定できるようになりました。
Autoload の強化
- config.autoload_lib
- config.autoload_lib_once
lib ディレクトリ以下にあるクラスやモジュールを自動読み込みする設定が追加された
以下のように指定することで、lib/assets, lib/tasks, lib/generators 以外の lib ディレクトリ内のファイルにある、モジュールやクラスが起動時に自動読み込みされ、起動中にファイルの変更を行った場合は(モデルやコントローラと同様に)リロードされる
config.autoload_lib(ignore: %w[assets tasks generators])
autoload_lib の代わりに config.autoload_lib_once を使用した場合は、起動時に1度だけ読み込まれ、変更後はリロードされない