Module: MongoidVersionedAtomic::VAtomic

Extended by:
ActiveSupport::Concern
Defined in:
lib/mongoid_versioned_atomic/v_atomic.rb

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



31
32
33
# File 'lib/mongoid_versioned_atomic/v_atomic.rb', line 31

def self.included(base)
    base.extend(ClassMethods)
end

Instance Method Details

#filter_fieldsObject

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.



166
167
168
169
170
171
172
173
# 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) ⇒ Object

after_persist sets the fields in the persisted document on the instance.



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# 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) ⇒ Object

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.



316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
# 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