@@ -105,17 +105,20 @@ def first!(spec)
105105 end
106106
107107 # saves a document. returns true on success, false on failure.
108+ # By default validations are run before saving. You can disable
109+ # validations by passing validate: false as an option.
110+ # You can also pass a custom validation context by passing context: :custom_context
108111 # if passed a block will:
109112 # * yield the object to be saved to the block and run if once before saving
110113 # * on conflict: reload the document, run the block again and retry saving
111- def save_document ( document , validate = true , retries = 0 , &block )
114+ def save_document ( document , options = { } , retries = 0 , &block )
112115 cache &.clear
113116 begin
114117 block &.call document
115- save_document_without_conflict_handling ( document , validate )
118+ save_document_without_conflict_handling ( document , options )
116119 rescue CouchRest ::Conflict
117120 if block
118- handle_write_conflict document , validate , retries , &block
121+ handle_write_conflict document , options , retries , &block
119122 else
120123 raise CouchPotato ::Conflict
121124 end
@@ -124,8 +127,8 @@ def save_document(document, validate = true, retries = 0, &block)
124127 alias save save_document
125128
126129 # saves a document, raises a CouchPotato::Database::ValidationsFailedError on failure
127- def save_document! ( document )
128- save_document ( document ) || raise ( ValidationsFailedError , document . errors . full_messages )
130+ def save_document! ( document , options = { } )
131+ save_document ( document , options ) || raise ( ValidationsFailedError , document . errors . full_messages )
129132 end
130133 alias save! save_document!
131134
@@ -293,15 +296,15 @@ def view_cache_id(spec)
293296 spec . send ( :klass ) . to_s + spec . view_name . to_s + spec . view_parameters . to_s
294297 end
295298
296- def handle_write_conflict ( document , validate , retries , &block )
299+ def handle_write_conflict ( document , options , retries , &block )
297300 cache &.clear
298301 if retries == 5
299302 raise CouchPotato ::Conflict
300303 else
301304 reloaded = document . reload
302305 document . attributes = reloaded . attributes
303306 document . _rev = reloaded . _rev
304- save_document document , validate , retries + 1 , &block
307+ save_document document , options , retries + 1 , &block
305308 end
306309 end
307310
@@ -314,11 +317,11 @@ def destroy_document_without_conflict_handling(document)
314317 document . _rev = nil
315318 end
316319
317- def save_document_without_conflict_handling ( document , validate = true )
320+ def save_document_without_conflict_handling ( document , options = { } )
318321 if document . new?
319- create_document ( document , validate )
322+ create_document ( document , options )
320323 else
321- update_document ( document , validate )
324+ update_document ( document , options )
322325 end
323326 end
324327
@@ -337,14 +340,15 @@ def bulk_load(ids)
337340 end
338341 end
339342
340- def create_document ( document , validate )
343+ def create_document ( document , options )
341344 document . database = self
345+ validate , validation_context = parse_save_options ( options )
342346
343347 if validate
344348 document . errors . clear
345349 return false if document . run_callbacks ( :validation_on_save ) do
346350 return false if document . run_callbacks ( :validation_on_create ) do
347- return false unless valid_document? ( document )
351+ return false unless valid_document? ( document , validation_context )
348352 end == false
349353 end == false
350354 end
@@ -360,12 +364,25 @@ def create_document(document, validate)
360364 true
361365 end
362366
363- def update_document ( document , validate )
367+ def parse_save_options ( options )
368+ if options . is_a? ( Hash )
369+ validate = options . fetch ( :validate , true )
370+ validation_context = options [ :context ]
371+ else
372+ validate = !!options
373+ validation_context = nil
374+ end
375+ [ validate , validation_context ]
376+ end
377+
378+ def update_document ( document , options )
379+ validate , validation_context = parse_save_options ( options )
380+
364381 if validate
365382 document . errors . clear
366383 return false if document . run_callbacks ( :validation_on_save ) do
367384 return false if document . run_callbacks ( :validation_on_update ) do
368- return false unless valid_document? ( document )
385+ return false unless valid_document? ( document , validation_context )
369386 end == false
370387 end == false
371388 end
@@ -380,9 +397,9 @@ def update_document(document, validate)
380397 true
381398 end
382399
383- def valid_document? ( document )
400+ def valid_document? ( document , validation_context = nil )
384401 original_errors_hash = document . errors . to_hash
385- document . valid?
402+ document . valid? ( validation_context )
386403 original_errors_hash . each do |k , v |
387404 if v . respond_to? ( :each )
388405 v . each { |message | document . errors . add ( k , message ) }
0 commit comments