Skip to content

Commit

Permalink
Adding upsert (before|after|around) callback
Browse files Browse the repository at this point in the history
  • Loading branch information
durran committed Jun 27, 2012
1 parent 2b04320 commit 3b1479f
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 2 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ For instructions on upgrading to newer versions, visit

### New Features

* A new callback has been introduced: `upsert`, which runs when calling
`document.upsert` since Mongoid does not know if the document is to be
treated as new or persisted. With this come the model callbacks:

before_upsert
after_upsert
around_upsert

* \#2080/\#2087 The database or session that Mongoid persists to can now be
overridden on a global level for cases where `Model#with` is not a viable
option.
Expand Down
5 changes: 4 additions & 1 deletion lib/mongoid/callbacks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@ module Callbacks
:after_initialize,
:after_save,
:after_update,
:after_upsert,
:after_validation,
:around_create,
:around_destroy,
:around_save,
:around_update,
:around_upsert,
:before_create,
:before_destroy,
:before_save,
:before_update,
:before_upsert,
:before_validation
]

Expand All @@ -30,7 +33,7 @@ module Callbacks

define_model_callbacks :initialize, only: :after
define_model_callbacks :build, only: :after
define_model_callbacks :create, :destroy, :save, :update
define_model_callbacks :create, :destroy, :save, :update, :upsert
end

# Run only the after callbacks for the specific event.
Expand Down
1 change: 1 addition & 0 deletions lib/mongoid/persistence.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require "mongoid/persistence/deletion"
require "mongoid/persistence/insertion"
require "mongoid/persistence/modification"
require "mongoid/persistence/upsertion"
require "mongoid/persistence/operations"

module Mongoid
Expand Down
2 changes: 1 addition & 1 deletion lib/mongoid/persistence/operations/upsert.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module Operations
# document has been modified or not, it will be sent to the db and Mongo
# will determin whether or not to insert or update.
class Upsert
include Modification, Operations
include Upsertion, Operations

# Persist the upsert operation.
#
Expand Down
30 changes: 30 additions & 0 deletions lib/mongoid/persistence/upsertion.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# encoding: utf-8
module Mongoid
module Persistence

# Contains common logic for upsert operations.
module Upsertion

# Wrap all the common upsert logic for root docments.
#
# @example Execute common upsert logic.
# prepare do |doc|
# collection.find({ :_id => 1 }).upsert({ name: "test" }, [ :upsert ])
# end
#
# @param [ Proc ] block The block to call.
#
# @return [ true, false ] If the save passed or not.
#
# @since 3.0.0
def prepare(&block)
return false if validating? && document.invalid?(:update)
result = document.run_callbacks(:upsert) do
yield(document); true
end
document.post_persist unless result == false
result
end
end
end
end
5 changes: 5 additions & 0 deletions spec/app/models/band.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@ class Band
field :likes, type: Integer
field :views, type: Integer
field :rating, type: Float
field :upserted, type: Boolean, default: false

embeds_many :records, cascade_callbacks: true
embeds_many :notes, as: :noteable, cascade_callbacks: true, validate: false
embeds_one :label, cascade_callbacks: true

after_upsert do |doc|
doc.upserted = true
end
end
4 changes: 4 additions & 0 deletions spec/mongoid/persistence/operations/upsert_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
it "returns true" do
persisted.should be_true
end

it "runs the upsert callbacks" do
band.upserted.should be_true
end
end

context "when the document is not new" do
Expand Down

0 comments on commit 3b1479f

Please sign in to comment.