SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Railsの新機能を知ろう!

Rails 7.1の新機能──非同期キュー、MySQLアダプター「Trilogy」やJavaScriptランタイム「Bun」の対応など

Railsの新機能を知ろう! 第2回

新たなシリアライザActiveSupport::MessagePackのサポート

 Rails 7.1では、新たなシリアライザとしてActiveSupport::MessagePackが利用できるようになりました。MessagePackは、msgpackに替わるシリアライザで、標準のRubyの型に加えて新たにTime、ActiveSupport::TimeWithZone、ActiveSupport::HashWithIndifferentAccessなどの型もシリアライズできます。また、JSONなどに比べてペイロードサイズが抑えられているので性能の向上を図れます。

 MessagePackは、Active Supportのメッセージシリアライザ、Action Dispatchのクッキーシリアライザ、他にはキャッシュシリアライザとして指定できます。以下はActive Supportのメッセージシリアライザを既定のJSONとMessagePackで比較した例です。

% rails c
# BigDecimal、Time、Hash、HashWithIndifferentAccessからなるタプルを生成
> data = [5.to_d, Time.now, { sym: 1 }, { str: 2 }.with_indifferent_access]
# JSONをシリアライザとするMessageVerifierを生成
> verifier = ActiveSupport::MessageVerifier.new("secret", digest: "SHA512", serializer: :json)
# メッセージを生成しベリファイ。BigDecimalやTime、Hashのキーは文字列になる
> message = verifier.generate(data)
> verifier.verified(message)
=> ["5.0", "2023-12-09T07:28:33.663+09:00", {"sym"=>1}, {"str"=>2}]
# MessagePackをシリアライザとするMessageVerifierを生成
> verifier = ActiveSupport::MessageVerifier.new("secret", digest: "SHA512", serializer: :message_pack)
# BigDecimalやTime、Hashのキーがシンボルである場合も適切にシリアライズされる
> message = verifier.generate(data)
> verifier.verified(message)
=> [0.5e1, 2023-12-09 07:28:33.663841 +0900, {:sym=>1}, {"str"=>2}]
# 型も見てみる
> verifier.verified(message).map(&:class)
=> [BigDecimal, Time, Hash, ActiveSupport::HashWithIndifferentAccess]

 既定のシリアライザは、application.rbファイルで以下のように設定できます。

リスト:config/application.rb
config.active_support.message_serializer = :message_pack
config.action_dispatch.cookies_serializer = :message_pack
config.cache_store = :file_store, "tmp/cache", { serializer: :message_pack }

 Active SupportのMessageEncryptorなどのクラスでも、個別にシリアライザの指定が可能です。

ActiveSupport::MessageEncryptor.new(secret, serializer: :message_pack)

明示的なテンプレート変数の指定

 Rails 7.1では、テンプレートが受け取る変数を厳密に指定できるようになりました。既定では、localsオプションで指定される全ての変数を受け取りますが、テンプレートが受け入れる変数を制限したり、既定値を与えることができます。これにより、テンプレートが想定しない変数を渡されたり、変数が省略された場合の対応が可能になります。

 変数は、テンプレートのマジックコメント構文にlocals:を記述して指定します。この場合、変数titleとview_countを受入れ、既定値はそれぞれ'No title'と0になります。

リスト:app/views/locals/show.html.erb
<%# locals: (title: 'No title', view_count: 0) -%>
<h1>タイトル:<%= title %></h1>
<p>ビュー数:<%= ciew_count %> 回</p>
# => ActionView::Template::Error (undefined local variable or method `ciew_count'

 コメントにない変数が渡されたり、既定値のない変数が省略されたりすると、Template::Errorが発生します。このように、テンプレートへの変数の引き渡しを厳密化できるので、より安全なテンプレートの利用が可能になります。

その他の便利な機能追加

 最後に、Active ModelやActive Recordで追加された便利な機能を紹介します。

Validatorオプションの機能拡張

 Active ModelのValidatorにおいて、幾つかのオプションの指定方法が拡張されました。

 まず、文字列長のバリデータLengthValidatorで指定できる:withinオプション、:inオプションで範囲(Range)を指定する場合の書式が変更になっています。従来は開始値と終了値の双方が必要でしたが、Rails 7.1ではそのいずれかを省略できるようになりました(双方の省略は不可)。これにより、例えばvalidates_length_ofメソッドで「何文字以下であるか」「何文字以上であるか」といったバリデーションの指定が容易になります。

リスト:app/models/user.rb
class User < ApplicationRecord
    # nameは20文字まで(空文字列もOK)
    validates_length_of :name, in: ..20
end

 また、包含のバリデータInclusionValidatorのvalidates_inclusion_ofメソッド、除外のバリデータExclusionValidatorのvalidates_exclusion_ofメソッドにおいては、開始値のみが省略できるようになりました。それぞれ、繰り返しオブジェクトの中に値が含まれるか(いないか)を検証するメソッドです。

リスト:app/models/user.rb
# birthが今日まではOK
validates_inclusion_of :birth, in: -> { (..Date.today) }
# birthが1900/1/1以降ならOK
validates_exclusion_of :birth, in: -> { (.."1899/12/31".to_date) }) }

 この他、比較のバリデータComparisonValidatorのvalidates_comparison_ofメソッドなどにカスタムバリデータを指定する場合、ラムダ式を与えるときはレコードそのものを表す引数を省略できるようになりました。従来は、例えラムダ式中で参照されなくても、引数としては必要でした。これは、Procオブジェクトを与えるときとの互換性のためです。

# Rails 7.0まで
validates_comparison_of :birth, less_than_or_equal_to: ->(x) { Date.today }
↓
# Rails 7.1
validates_comparison_of :birth, less_than_or_equal_to: -> { Date.today }

whereメソッド引数のタプル受入れ

 第1回で、Active Recordにおける複合主キーのサポートを紹介しました。そこでは、複合主キーのためにfindメソッドが主キーのタプルを受け入れることを紹介しましたが、それと同時にRails 7.1ではwhereメソッドにもタプル構文が導入されました。これにより、クエリに含まれるキーと値の対応が分かりやすくなります。

% rails c
> Book.create!(title: 'Rails Primer', author: 'Nao Yamauchi')
> Book.create!(title: 'Good Ruby', author: 'Shino Onodera')
> Book.where([:title, :author] => [['Rails Primer', 'Nao Yamauchi'], ['Good Ruby', 'Shino Onodera']])
SELECT "books".* FROM "books" WHERE ("books"."title" = ? AND "books"."author" = ? OR "books"."title" = ? AND "books"."author" = ?) LIMIT ?  [["title", "Rails Primer"], ["author", "Nao Yamauchi"], ["title", "Good Ruby"], ["author", "Shino Onodera"], ["LIMIT", 11]]

 キーのタプルに値のタプルを指定することで、値の組み合わせに一致するレコードのAND検索が容易です。値のタプルを複数指定すれば、それはOR検索となります。もともとは、複合主キーによる検索をwhereメソッドでも可能にする改変で、複合主キーをクエリに指定するときは以下のようにprimary_keyフィールドを使って記述できます。

% rails c
> Order.create!(customer_id: 1, product_id: 2, quantity: 10)
> Order.create!(customer_id: 2, product_id: 4, quantity: 20)
> Order.where(Order.primary_key => [[1, 2], [2, 4]]).count
=> 2

まとめ

 今回は、Ruby on Rails 7.1の新機能のうち、非同期キューや新しいJavaScriptランタイム環境などの機能強化について紹介しました。

 Railsは、絶え間ない進化を成し遂げています。次の進化でも、改めてその概要をお伝えできればと思います。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
Railsの新機能を知ろう!連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 山内 直(WINGSプロジェクト ヤマウチ ナオ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook <個人紹介>WINGSプロジェクト所属のテクニカルライター。出版社を経てフリーランスとして独立。ライター、エディター、デベロッパー、講師業に従事。屋号は「たまデジ。」。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/18896 2024/02/02 11:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー