blob: 8cdb8e0765e03fde93cd94a0970351df7054ee81 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
# 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
|