Browse files

Implementation of making embedded callbacks optional.

Something to get the discussion started...
  • Loading branch information...
1 parent 1a4cb8d commit fefec91027f2dd8eb1ab9caa5a4b0acd000f4da7 @jnunemaker jnunemaker committed Apr 16, 2012
Showing with 82 additions and 11 deletions.
  1. +33 −9 lib/mongo_mapper/plugins/embedded_callbacks.rb
  2. +49 −2 test/functional/test_callbacks.rb
View
42 lib/mongo_mapper/plugins/embedded_callbacks.rb
@@ -9,22 +9,46 @@ module EmbeddedCallbacks
define_model_callbacks :save, :create, :update, :destroy, :only => [:before, :after]
define_model_callbacks :touch, :only => [:after]
+
+ embedded_callbacks_on
end
- def run_callbacks(callback, *args, &block)
- embedded_docs = []
+ module ClassMethods
+ def embedded_callbacks_on
+ @embedded_callbacks_status = true
+ end
+
+ def embedded_callbacks_off
+ @embedded_callbacks_status = false
+ end
+
+ def embedded_callbacks_on?
+ @embedded_callbacks_status == true
+ end
- embedded_associations.each do |association|
- embedded_docs += Array(get_proxy(association).send(:load_target))
+ def embedded_callbacks_off?
+ !embedded_callbacks_on?
end
+ end
+
+ def run_callbacks(callback, *args, &block)
+
+ if self.class.embedded_callbacks_on?
+ embedded_docs = []
- block = embedded_docs.inject(block) do |chain, doc|
- if doc.class.respond_to?("_#{callback}_callbacks")
- lambda { doc.run_callbacks(callback, *args, &chain) }
- else
- chain
+ embedded_associations.each do |association|
+ embedded_docs += Array(get_proxy(association).send(:load_target))
+ end
+
+ block = embedded_docs.inject(block) do |chain, doc|
+ if doc.class.respond_to?("_#{callback}_callbacks")
+ lambda { doc.run_callbacks(callback, *args, &chain) }
+ else
+ chain
+ end
end
end
+
super callback, *args, &block
end
end
View
51 test/functional/test_callbacks.rb
@@ -106,7 +106,7 @@ class CallbacksTest < Test::Unit::TestCase
@child_class = EDoc { include CallbacksSupport }
@grand_child_class = EDoc { include CallbacksSupport }
- @root_class.many :children, :class => @child_class
+ @root_class.many :children, :class => @child_class
@child_class.many :children, :class => @grand_child_class
end
@@ -156,13 +156,60 @@ class CallbacksTest < Test::Unit::TestCase
end
end
+ context "Turning embedded callbacks off" do
+ setup do
+ @root_class = Doc { include CallbacksSupport; embedded_callbacks_off }
+ @child_class = EDoc { include CallbacksSupport; embedded_callbacks_off }
+ @grand_child_class = EDoc { include CallbacksSupport; embedded_callbacks_off }
+
+ @root_class.many :children, :class => @child_class
+ @child_class.many :children, :class => @grand_child_class
+
+ @root_class.many :children, :class => @child_class
+ @child_class.many :children, :class => @grand_child_class
+ end
+
+ should "not run create callbacks" do
+ grand = @grand_child_class.new(:name => 'Grand Child')
+ child = @child_class.new(:name => 'Child', :children => [grand])
+ root = @root_class.create(:name => 'Parent', :children => [child])
+
+ root.children.first.history.should == []
+ root.children.first.children.first.history.should == []
+ end
+
+ should "not run update callbacks" do
+ grand = @grand_child_class.new(:name => 'Grand Child')
+ child = @child_class.new(:name => 'Child', :children => [grand])
+ root = @root_class.create(:name => 'Parent', :children => [child])
+ root.clear_history
+ root.update_attributes(:name => 'Updated Parent')
+
+ root.children.first.history.should == []
+ root.children.first.children.first.history.should == []
+ end
+
+ should "not run destroy callbacks" do
+ grand = @grand_child_class.new(:name => 'Grand Child')
+ child = @child_class.new(:name => 'Child', :children => [grand])
+ root = @root_class.create(:name => 'Parent', :children => [child])
+ root.destroy
+ child = root.children.first
+ child.history.should == []
+
+ grand = root.children.first.children.first
+ grand.history.should == []
+ end
+ end
+
context "Running validation callbacks with conditional execution" do
setup do
@document = Doc do
include CallbacksSupport
key :message, String
before_validation :set_message, :on => 'create'
+
def set_message
self['message'] = 'Hi!'
end
@@ -182,4 +229,4 @@ def set_message
doc.message.should == 'Ho!'
end
end
-end
+end

2 comments on commit fefec91

@bkeepers

I don't love the naming. What about #enable_embedded_callbacks and #disable_embedded_callbacks?

@jnunemaker
Please sign in to comment.