Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

Rails 7: Active ModelからActiveModel::APIが切り出された(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

日本語タイトルは内容に即したものにしました。

参考: 週刊Railsウォッチ20210921 ActiveModel::APIが追加

Rails 7: Active ModelからActiveModel::APIが切り出された(翻訳)

私たちはRailsで作業するときにActive Recordに慣れ親しんでいます。Active RecordはMVCフレームワークにおけるモデルであり、システムでビジネスデータやビジネスロジックの表現を担当する層です。Active Recordは、アプリケーション内のリッチなオブジェクトをRDBMS上のテーブルに接続するORM(Object-relational mapping)でもあります。

Railsで、データベース内のどのテーブルとも紐付けられていない普通のクラスが、モデルのような機能を必要とすることがあります。こういうときはRailsのActive Modelの出番です。Active Modelは、Active Recordの機能の一部を必要とするクラスを開発するときに使われるライブラリです。

たとえばname属性とid属性を持つPersonクラスがあるとします。これらの属性をバリデーションする機能を追加したい場合は、 ActiveModelを使うことで以下のようにPersonクラスを実装できます。

class Person
  include ActiveModel::Model

  attr_accessor :name, :email
  validates :name, :email, presence: true
end
irb> person = Person.new(name: "Sam", email: "sam@example.com")

irb> person.name
# => "Sam"

irb> person.email
# => "sam@example.com"

irb> person.valid?
# => true

irb> person.persisted?
# => false

ActiveModel::Modelincludeすれば、以下のような機能も使えるようになります。

  • モデル名を調べる
  • ActiveModel::Conversion(変換)
  • ActiveModel::Translation(翻訳)
  • ActiveModel::Validator(バリデーション)

ActiveModel::Modelincludeしたクラスでは、Active Recordオブジェクトと同じようにform_withrenderなどのAction Viewヘルパーメソッドが使えるようになります。

変更前

Rails 7より前のActiveModel::Modelは、Action PackやAction Viewとやりとりする最小限のAPIとして動作します。

「Model」という名前から分かるように、ActiveModel::ModelincludeすればActive Recordのようなモデルを作成できます。しかしActiveModel::Modelでは、基本的なActiveModel::Attributes機能がサポートされていませんでした。

attributeメソッドを使おうとして失敗する様子をちょっと見てみましょう。

class Person
  include ActiveModel::Model

  attribute :name, :string
  attribute :email, :string
end

NoMethodError (undefined method `attribute' for Person:Class)

これを解決するには、PersonクラスにActiveModel::Attributesincludeする必要があります。

変更後

Rails 7以降は、ActiveModel::Modelの実装がActiveModel::APIに移動します(#43223)。

ActiveModel::API がAction PackやAction Viewとやりとりするときの定義は最小限に抑えられています。これにより、ActiveModel::Modelは、今後Active Recordのモデルのような機能を追加して拡張できます。

ActiveModel::ModelActiveModel::APIだけをincludeするようになりました。このおかげで、後方互換性を維持しながらモデルに機能を追加できるようになりました。

関連記事

Rails 7: caching?とuncachable!ヘルパーが追加(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。