aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/no_touching.rb
diff options
context:
space:
mode:
authorDamien Mathieu <42@dmathieu.com>2013-11-05 13:44:16 +0100
committerDamien Mathieu <42@dmathieu.com>2013-11-13 08:42:38 +0100
commitb32ba367f584a6298fb8b7eef97be15388b5bd87 (patch)
treee1667de04ac1a7a8bfa9704713af8de231a0b055 /activerecord/lib/active_record/no_touching.rb
parentbba8bb8b4020bb5e79784f2395a53e8cde8e82eb (diff)
downloadrails-b32ba367f584a6298fb8b7eef97be15388b5bd87.tar.gz
rails-b32ba367f584a6298fb8b7eef97be15388b5bd87.tar.bz2
rails-b32ba367f584a6298fb8b7eef97be15388b5bd87.zip
add #no_touching on ActiveRecord models
Diffstat (limited to 'activerecord/lib/active_record/no_touching.rb')
-rw-r--r--activerecord/lib/active_record/no_touching.rb52
1 files changed, 52 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/no_touching.rb b/activerecord/lib/active_record/no_touching.rb
new file mode 100644
index 0000000000..dbf4564ae5
--- /dev/null
+++ b/activerecord/lib/active_record/no_touching.rb
@@ -0,0 +1,52 @@
+module ActiveRecord
+ # = Active Record No Touching
+ module NoTouching
+ extend ActiveSupport::Concern
+
+ module ClassMethods
+ # Lets you selectively disable calls to `touch` for the
+ # duration of a block.
+ #
+ # ==== Examples
+ # ActiveRecord::Base.no_touching do
+ # Project.first.touch # does nothing
+ # Message.first.touch # does nothing
+ # end
+ #
+ # Project.no_touching do
+ # Project.first.touch # does nothing
+ # Message.first.touch # works, but does not touch the associated project
+ # end
+ #
+ def no_touching(&block)
+ NoTouching.apply_to(self, &block)
+ end
+ end
+
+ class << self
+ def apply_to(klass) #:nodoc:
+ klasses.push(klass)
+ yield
+ ensure
+ klasses.pop
+ end
+
+ def applied_to?(klass) #:nodoc:
+ klasses.any? { |k| k >= klass }
+ end
+
+ private
+ def klasses
+ Thread.current[:no_touching_classes] ||= []
+ end
+ end
+
+ def no_touching?
+ NoTouching.applied_to?(self.class)
+ end
+
+ def touch(*)
+ super unless no_touching?
+ end
+ end
+end