diff options
author | Rafael Mendonça França <rafael.franca@plataformatec.com.br> | 2015-02-19 09:04:31 -0200 |
---|---|---|
committer | Rafael Mendonça França <rafael.franca@plataformatec.com.br> | 2015-02-19 09:04:31 -0200 |
commit | 41b9730c6d033ea7f38fae4d18347c5370ff7b6c (patch) | |
tree | e28e9420ff4180b9d2dc7e7f79abefc58c3ff657 /activerecord/lib/active_record/suppressor.rb | |
parent | 06d5d2c5e9cfcd92ba239703c0d699d17a90621e (diff) | |
parent | b9a1e9a4b2289de199b214a542aa9fd3cb19be54 (diff) | |
download | rails-41b9730c6d033ea7f38fae4d18347c5370ff7b6c.tar.gz rails-41b9730c6d033ea7f38fae4d18347c5370ff7b6c.tar.bz2 rails-41b9730c6d033ea7f38fae4d18347c5370ff7b6c.zip |
Merge pull request #18910 from perceptec/add_suppressor
Add `ActiveRecord::Base.suppress` to allow save events to be suppressed within a specified block.
Diffstat (limited to 'activerecord/lib/active_record/suppressor.rb')
-rw-r--r-- | activerecord/lib/active_record/suppressor.rb | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/suppressor.rb b/activerecord/lib/active_record/suppressor.rb new file mode 100644 index 0000000000..b47f02143c --- /dev/null +++ b/activerecord/lib/active_record/suppressor.rb @@ -0,0 +1,55 @@ +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) + SuppressorRegistry.suppressed[name] = true + yield + ensure + SuppressorRegistry.suppressed[name] = false + end + end + + # Ignore saving events if we're in suppression mode. + def save!(*args) + SuppressorRegistry.suppressed[self.class.name] ? self : super + end + end + + class SuppressorRegistry # :nodoc: + extend ActiveSupport::PerThreadRegistry + + attr_reader :suppressed + + def initialize + @suppressed = {} + end + end +end |