👋
Railsで保存を抑制するActiveRecord#suppress
どんなものなのか?
具体的には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から使えるようでした。
ほんと勉強になりますねぇ。
Discussion