👋

Railsで保存を抑制するActiveRecord#suppress

2023/08/21に公開

どんなものなのか?

具体的にはActiveRecord#suppressブロックの中でデータが保存されるのを防ぐ仕組みです。

サンプルコード

たとえばMessageモデルのコールバックのafter_create_commitで通知テーブルへの書き込みをするような実装になってることがよくあったりするかと思います。

class Message < ApplicationRecord
  belongs_to :user

  after_create_commit :create_notification

  def create_notification
    Notification.create(user: user, content: content)
  end
end

ここでよくやりがちなのが、条件分岐をコールバック側で設定したり、skip_callbackをしてしまったりということで意図しない挙動を引き起こしてエラーになったり、書き込まれて欲しいものが書き込まれなかったりと不幸な事故を起こしてきました。

ここで下記のようにNotification.suppressを使うと、通知テーブルへの書き込みが抑制されるようになります。

Notification.suppress do 
  Message.create(message_params) # Notificationへの書き込みが抑制され、Notificationモデルの作成がされない。
end

用途

例えば想い浮かぶのは、Railsのコールバックで書き込まれると都合が悪い場合に場合に利用します。
skip_callbackはスレッドセーフでなかったりとなかなか厄介者だったので、もしスレッドセーフであれば活用することでモデルのコールバックの悩みを少し軽減することができるかもしれないです。

いつから使えたのか?

ActiveRecord#suppress自体はRails5.0から使えるようでした。
ほんと勉強になりますねぇ。

OSIRO テックブログ

Discussion