Skip to content

Commit

Permalink
Implementation of making embedded callbacks optional.
Browse files Browse the repository at this point in the history
Something to get the discussion started...
  • Loading branch information
jnunemaker committed Apr 16, 2012
1 parent 1a4cb8d commit fefec91
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 11 deletions.
42 changes: 33 additions & 9 deletions lib/mongo_mapper/plugins/embedded_callbacks.rb
Expand Up @@ -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
Expand Down
51 changes: 49 additions & 2 deletions test/functional/test_callbacks.rb
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -182,4 +229,4 @@ def set_message
doc.message.should == 'Ho!'
end
end
end
end

2 comments on commit fefec91

@bkeepers
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@jnunemaker
Copy link
Contributor Author

@jnunemaker jnunemaker commented on fefec91 Apr 17, 2012 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.