module MongoidVersionedAtomic::VAtomic
Public Class Methods
included(base)
click to toggle source
# File lib/mongoid_versioned_atomic/v_atomic.rb, line 31 def self.included(base) base.extend(ClassMethods) end
Public Instance Methods
filter_fields()
click to toggle source
removes "version" and "op_success" fields from the document before save or update, this ensures that these fields can only be persisted by the versioned_create and versioned_update methods. prevents inadvertent persistence of these fields.
return attributes : the document as a set of key-value fields.
# File lib/mongoid_versioned_atomic/v_atomic.rb, line 166 def filter_fields remove_attribute(:version) remove_attribute(:op_success) attributes end
versioned_create(query={},log=false)
click to toggle source
after_persist sets the fields in the persisted document on the instance.
# File lib/mongoid_versioned_atomic/v_atomic.rb, line 226 def versioned_create(query={},log=false) self.send("op_success=",false) update = {} options = {} id_query = {"_id" => as_document["_id"]} query = query.empty? ? id_query : query if version == 0 update["$setOnInsert"] = {} options[:upsert] = true expected_version = 1 prepare_insert(options) do as_document.keys.each do |k| if (k != "version" && k != "op_success") update["$setOnInsert"][k] = self.send(k.to_sym) end end update["$setOnInsert"]["version"] = 1 options,update = self.class.before_persist(options,update,true) self.class.log_opts(query,update,options,"create",log) write_result = collection.update_one(query,update,options) self.matched_count = write_result.matched_count self.modified_count = write_result.modified_count self.upserted_id = write_result.upserted_id ##as long as it matched a document, or it inserted a document if self.upserted_id self.send("op_success=",true) self.version = 1 else self.send("op_success=",false) end end end return query,update,options end
versioned_update(dirty_fields={},bypass_versioning=false,optional_update_hash={},log=false)
click to toggle source
finally call after_persist to set all the changed fields on the document. this becomes relevant especially in case where you pass in an optional update hash with an “$inc” for some field. The incremented value is not there on the instance, since the instance has the older value and this must be set if the op is successfull on the instance.
# File lib/mongoid_versioned_atomic/v_atomic.rb, line 316 def versioned_update(dirty_fields={},bypass_versioning=false,optional_update_hash={},log=false) self.send("op_success=",false) query = {} options = {} update = {} curr_doc = as_document ##if the dirty fields are empty then it becomes equal to a hash whose keys are the document attributes, and whose values for each key are nil, ##otherwise dirty_fields stays as it is. dirty_fields = dirty_fields.empty? ? Hash[curr_doc.keys.zip([])] : dirty_fields if curr_doc["version"] > 0 if !bypass_versioning query["version"] = curr_doc["version"] end query["_id"] = curr_doc["_id"] update["$set"] = {} options[:upsert] = false expected_version = curr_doc["version"] + 1 ##what happens is that we send the update["$set"][k] to whatever was stored in the dirty_fields. prepare_update(options) do dirty_fields.keys.each do |k| if (k != "version" && k != "_id" && k != "op_success") update["$set"][k] = self.send(k.to_sym) end end update = optional_update_hash.empty? ? update : optional_update_hash options,update = self.class.before_persist(options,update,bypass_versioning) #puts "-----------------------------------" #puts "called update" #puts "-----------------------------------" self.class.log_opts(query,update,options,"update",log) write_result = collection.update_one(query,update,options) if write_result.modified_count == 1 self.send("op_success=",true) persisted_doc = self.class.to_s.constantize.find(self.to_param) persisted_doc = persisted_doc.attributes self.class.after_persist(persisted_doc,self) else self.send("op_success=",false) end end end return query,update,options end