Rails 7: belongs_to関連付けに変更トラッキングが追加(翻訳)
アップデートとしては地味でも、Railsユーザーにとって嬉しさ最大の機能が登場することがあります。Railsの最近のアップデートで、belongs_to
関連付けの変更を監視する機能が導入されました。Rails wayに沿って進めたい開発者にとっては大歓迎です。
変更トラッキングは、Railsですぐ使える便利メソッドの一種です。Active Recordを使っていると、データベースで変更が生じているかどうかを調べられます。これはトリガーやイベントをビルドするときに便利です。サンプルを見てみましょう。
データベース構造に投稿(Post)とカテゴリ(Category)があるとします。
class Post
belongs_to :category
end
class Category
has_many :posts
end
投稿のタイトルが変更されたときのアクティビティを記録しておきたいとします。これは以下のように書けます。
class Post
belongs_to :category
before_update :record_activity
private
def record_activity
if self.title_changed?
# record an activity
end
end
end
title
属性の値が変更されたかどうかはtitle_changed?
メソッドで監視できます。
変更前
同じことを、投稿のカテゴリが変更された場合についてもやってみましょう。
class Post
belongs_to :category
before_update :record_activity
private
def record_activity
if self.category_id_changed?
# アクティビティを記録する
end
end
end
この書き方は目障りですね。category
という関連付けがあるにもかかわらず、その関連付けの変更を追えないので、category_id
の変更を監視するというかなり大雑把な方法を取らざるを得ません。これではRails wayから遠ざかってしまいます。
変更後
ありがたいことに、Rails 7でこれを行う方法が導入されます(#42751)。これなら以下のように書けます。
class Post
belongs_to :category
before_update :record_activity
private
def record_activity
if self.category_changed?
# アクティビティを記録する
end
end
end
この関連付け名_changed?
メソッドは、元と異なる関連付けオブジェクトが代入されている場合はtrueを返し、次回のsave!
で外部キーが更新されます。
また、関連付け名_previously_changed?
を使えば、以下のように直前のsave
で関連付けが更新されて元と異なる関連付けオブジェクトを参照する場合はtrueを返すこともできます。
post.category # => #<Post category_id: 123, title: "Welcome to Rails!">
post.category_previously_changed? # => false
post.category = Category.second # => #<Post category_id: 456, title: "Welcome to Rails!">
post.save!
post.category_previously_changed? # => true
概要
原著者の許諾を得て翻訳・公開いたします。