blob: 8cdb8e0765e03fde93cd94a0970351df7054ee81 (
plain) (
tree)
|
|
# frozen_string_literal: true
module ActiveRecord
# ActiveRecord::Suppressor prevents the receiver from being saved during
# a given block.
#
# For example, here's a pattern of creating notifications when new comments
# are posted. (The notification may in turn trigger an email, a push
# notification, or just appear in the UI somewhere):
#
# class Comment < ActiveRecord::Base
# belongs_to :commentable, polymorphic: true
# after_create -> { Notification.create! comment: self,
# recipients: commentable.recipients }
# end
#
# That's what you want the bulk of the time. New comment creates a new
# Notification. But there may well be off cases, like copying a commentable
# and its comments, where you don't want that. So you'd have a concern
# something like this:
#
# module Copyable
# def copy_to(destination)
# Notification.suppress do
# # Copy logic that creates new comments that we do not want
# # triggering notifications.
# end
# end
# end
module Suppressor
extend ActiveSupport::Concern
module ClassMethods
def suppress(&block)
previous_state = SuppressorRegistry.suppressed[name]
SuppressorRegistry.suppressed[name] = true
yield
ensure
SuppressorRegistry.suppressed[name] = previous_state
end
end
def save(*) # :nodoc:
SuppressorRegistry.suppressed[self.class.name] ? true : super
end
def save!(*) # :nodoc:
SuppressorRegistry.suppressed[self.class.name] ? true : super
end
end
class SuppressorRegistry # :nodoc:
extend ActiveSupport::PerThreadRegistry
attr_reader :suppressed
def initialize
@suppressed = {}
end
end
end
|