Skip to content

Commit

Permalink
Added before/after create, update, save and destroy callbacks.
Browse files Browse the repository at this point in the history
  • Loading branch information
jnunemaker committed May 28, 2009
1 parent a4e7329 commit eae62f0
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 5 deletions.
19 changes: 19 additions & 0 deletions lib/mongo_mapper/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ module Document
def self.included(model)
model.extend ClassMethods
model.class_eval do
include ActiveSupport::Callbacks

define_callbacks :before_create, :after_create,
:before_update, :after_update,
:before_save, :after_save,
:before_destroy, :after_destroy

key :_id, String
key :created_at, Time
key :updated_at, Time
Expand Down Expand Up @@ -177,8 +184,14 @@ def new_record?
read_attribute('_id').blank? || self.class.find_by_id(id).blank?
end

def valid?
true
end

def save
run_callbacks(:before_save)
new_record? ? create : update
run_callbacks(:after_save)
self
end

Expand All @@ -188,7 +201,9 @@ def update_attributes(attrs={})
end

def destroy
run_callbacks(:before_destroy)
collection.remove(:_id => id) unless new_record?
run_callbacks(:after_destroy)
freeze
end

Expand Down Expand Up @@ -254,12 +269,16 @@ def inspect
def create
write_attribute('_id', generate_id) if read_attribute('_id').blank?
update_document_timestamps
run_callbacks(:before_create)
collection.insert(attributes)
run_callbacks(:after_create)
end

def update
update_document_timestamps
run_callbacks(:before_update)
collection.modify({:_id => id}, attributes)
run_callbacks(:after_update)
end

def update_document_timestamps
Expand Down
60 changes: 60 additions & 0 deletions test/test_callbacks.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
require 'test_helper'

include ActiveSupport::Callbacks

class CallbacksTest < Test::Unit::TestCase
context "Defining and running callbacks" do
setup do
@document = Class.new
@document.class_eval do
include MongoMapper::Document

key :name, String

%w(before_create after_create before_update after_update
before_save after_save before_destroy after_destroy).each do |callback|
callback_method = "#{callback}_callback"
send(callback, callback_method)
define_method(callback_method) do
history << callback.to_sym
end
end

def history
@history ||= []
end
end
@document.collection.clear
end

should "work for before and after create" do
doc = @document.create(:name => 'John Nunemaker')
doc.history.should include(:before_create)
doc.history.should include(:after_create)
end

should "work for before and after update" do
doc = @document.create(:name => 'John Nunemaker')
doc.name = 'John Doe'
doc.save
doc.history.should include(:before_update)
doc.history.should include(:after_update)
end

should "work for before and after save" do
doc = @document.new
doc.name = 'John Doe'
doc.save
doc.history.should include(:before_save)
doc.history.should include(:after_save)
end

should "work for before and after destroy" do
doc = @document.create(:name => 'John Nunemaker')
doc.destroy
doc.history.should include(:before_destroy)
doc.history.should include(:after_destroy)
end
end

end
10 changes: 5 additions & 5 deletions test/test_document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class DocumentTest < Test::Unit::TestCase
context "The Document Class" do
setup do
@document = Class.new
@document.instance_eval { include MongoMapper::Document }
@document.class_eval { include MongoMapper::Document }
end

should "should be able to define a key" do
Expand Down Expand Up @@ -43,7 +43,7 @@ class DocumentTest < Test::Unit::TestCase
@document.database.name.should == AlternateDatabase

another_document = Class.new
another_document.instance_eval { include MongoMapper::Document }
another_document.class_eval { include MongoMapper::Document }
another_document.database.should == MongoMapper.database
end

Expand All @@ -62,7 +62,7 @@ class DocumentTest < Test::Unit::TestCase
context "Database operations" do
setup do
@document = Class.new
@document.instance_eval do
@document.class_eval do
include MongoMapper::Document
collection 'users'

Expand Down Expand Up @@ -379,7 +379,7 @@ class DocumentTest < Test::Unit::TestCase
context "An instance of a document" do
setup do
@document = Class.new
@document.instance_eval do
@document.class_eval do
include MongoMapper::Document

key :name, String
Expand Down Expand Up @@ -579,7 +579,7 @@ def name_and_age=(new_value)

should "not be equal if id same but class different" do
@another_document = Class.new
@another_document.instance_eval { include MongoMapper::Document }
@another_document.class_eval { include MongoMapper::Document }

(@document.new('_id' => 1) == @another_document.new('_id' => 1)).should be(false)
end
Expand Down

0 comments on commit eae62f0

Please sign in to comment.