couch_potato 1.19.2 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +1 -1
- data/CHANGES.md +4 -0
- data/lib/couch_potato/database.rb +33 -16
- data/lib/couch_potato/version.rb +1 -1
- data/spec/spec_helper.rb +10 -0
- data/spec/validation_context_spec.rb +84 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3550e8fe5b60fb064f2960a62313ee43e41e28c980c7c7d395d6c252fdb4fa20
|
|
4
|
+
data.tar.gz: 4aff0328b8e0e2162793c8b7f81643a5a3a43b703a64b00c57f044c12aac0ab0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 676096f6f62795015a3bb26b6fe27689eda09aacb59f05c1f181a2922bc968fd762a9571ef02085425071212cf3ee1c688d36caaf06ee68dafe134d6bf9c04ae
|
|
7
|
+
data.tar.gz: 49582697b2508b97fc73a9a1a0590e6882f138577ea5ab6492746a61ab654b74170830cf9c61b4de1b36f002bd344b0b193f903dec6dc78e10f6a3f5d2c7c9d1
|
data/.github/workflows/ruby.yml
CHANGED
data/CHANGES.md
CHANGED
|
@@ -105,17 +105,20 @@ module CouchPotato
|
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
# 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
|
|
108
111
|
# if passed a block will:
|
|
109
112
|
# * yield the object to be saved to the block and run if once before saving
|
|
110
113
|
# * on conflict: reload the document, run the block again and retry saving
|
|
111
|
-
def save_document(document,
|
|
114
|
+
def save_document(document, options = {}, retries = 0, &block)
|
|
112
115
|
cache&.clear
|
|
113
116
|
begin
|
|
114
117
|
block&.call document
|
|
115
|
-
save_document_without_conflict_handling(document,
|
|
118
|
+
save_document_without_conflict_handling(document, options)
|
|
116
119
|
rescue CouchRest::Conflict
|
|
117
120
|
if block
|
|
118
|
-
handle_write_conflict document,
|
|
121
|
+
handle_write_conflict document, options, retries, &block
|
|
119
122
|
else
|
|
120
123
|
raise CouchPotato::Conflict
|
|
121
124
|
end
|
|
@@ -124,8 +127,8 @@ module CouchPotato
|
|
|
124
127
|
alias save save_document
|
|
125
128
|
|
|
126
129
|
# 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)
|
|
129
132
|
end
|
|
130
133
|
alias save! save_document!
|
|
131
134
|
|
|
@@ -293,7 +296,7 @@ module CouchPotato
|
|
|
293
296
|
spec.send(:klass).to_s + spec.view_name.to_s + spec.view_parameters.to_s
|
|
294
297
|
end
|
|
295
298
|
|
|
296
|
-
def handle_write_conflict(document,
|
|
299
|
+
def handle_write_conflict(document, options, retries, &block)
|
|
297
300
|
cache&.clear
|
|
298
301
|
if retries == 5
|
|
299
302
|
raise CouchPotato::Conflict
|
|
@@ -301,7 +304,7 @@ module CouchPotato
|
|
|
301
304
|
reloaded = document.reload
|
|
302
305
|
document.attributes = reloaded.attributes
|
|
303
306
|
document._rev = reloaded._rev
|
|
304
|
-
save_document document,
|
|
307
|
+
save_document document, options, retries + 1, &block
|
|
305
308
|
end
|
|
306
309
|
end
|
|
307
310
|
|
|
@@ -314,11 +317,11 @@ module CouchPotato
|
|
|
314
317
|
document._rev = nil
|
|
315
318
|
end
|
|
316
319
|
|
|
317
|
-
def save_document_without_conflict_handling(document,
|
|
320
|
+
def save_document_without_conflict_handling(document, options = {})
|
|
318
321
|
if document.new?
|
|
319
|
-
create_document(document,
|
|
322
|
+
create_document(document, options)
|
|
320
323
|
else
|
|
321
|
-
update_document(document,
|
|
324
|
+
update_document(document, options)
|
|
322
325
|
end
|
|
323
326
|
end
|
|
324
327
|
|
|
@@ -337,14 +340,15 @@ module CouchPotato
|
|
|
337
340
|
end
|
|
338
341
|
end
|
|
339
342
|
|
|
340
|
-
def create_document(document,
|
|
343
|
+
def create_document(document, options)
|
|
341
344
|
document.database = self
|
|
345
|
+
validate, validation_context = parse_save_options(options)
|
|
342
346
|
|
|
343
347
|
if validate
|
|
344
348
|
document.errors.clear
|
|
345
349
|
return false if document.run_callbacks(:validation_on_save) do
|
|
346
350
|
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)
|
|
348
352
|
end == false
|
|
349
353
|
end == false
|
|
350
354
|
end
|
|
@@ -360,12 +364,25 @@ module CouchPotato
|
|
|
360
364
|
true
|
|
361
365
|
end
|
|
362
366
|
|
|
363
|
-
def
|
|
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
|
+
|
|
364
381
|
if validate
|
|
365
382
|
document.errors.clear
|
|
366
383
|
return false if document.run_callbacks(:validation_on_save) do
|
|
367
384
|
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)
|
|
369
386
|
end == false
|
|
370
387
|
end == false
|
|
371
388
|
end
|
|
@@ -380,9 +397,9 @@ module CouchPotato
|
|
|
380
397
|
true
|
|
381
398
|
end
|
|
382
399
|
|
|
383
|
-
def valid_document?(document)
|
|
400
|
+
def valid_document?(document, validation_context = nil)
|
|
384
401
|
original_errors_hash = document.errors.to_hash
|
|
385
|
-
document.valid?
|
|
402
|
+
document.valid?(validation_context)
|
|
386
403
|
original_errors_hash.each do |k, v|
|
|
387
404
|
if v.respond_to?(:each)
|
|
388
405
|
v.each { |message| document.errors.add(k, message) }
|
data/lib/couch_potato/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
|
@@ -39,6 +39,16 @@ class BigDecimalContainer
|
|
|
39
39
|
property :number, type: BigDecimal
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
class WithValidationContext
|
|
43
|
+
include CouchPotato::Persistence
|
|
44
|
+
|
|
45
|
+
property :name
|
|
46
|
+
|
|
47
|
+
validates_presence_of :name, on: :create
|
|
48
|
+
validates_length_of :name, minimum: 5, on: :update
|
|
49
|
+
validates_length_of :name, minimum: 10, on: :custom
|
|
50
|
+
end
|
|
51
|
+
|
|
42
52
|
def recreate_db
|
|
43
53
|
CouchPotato.couchrest_database.recreate!
|
|
44
54
|
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "validation context" do
|
|
4
|
+
let(:db) { CouchPotato.database }
|
|
5
|
+
|
|
6
|
+
context 'when calling save' do
|
|
7
|
+
|
|
8
|
+
it 'uses the :create context on creation' do
|
|
9
|
+
model = WithValidationContext.new
|
|
10
|
+
|
|
11
|
+
db.save(model)
|
|
12
|
+
|
|
13
|
+
expect(model.errors[:name]).to eq(["can't be blank"])
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'uses the :update context on update' do
|
|
17
|
+
model = WithValidationContext.new(name: 'initial name')
|
|
18
|
+
db.save!(model)
|
|
19
|
+
|
|
20
|
+
model.name = 'new'
|
|
21
|
+
db.save(model)
|
|
22
|
+
|
|
23
|
+
expect(model.errors[:name]).to eq(["is too short (minimum is 5 characters)"])
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'uses a custom context on create when specified' do
|
|
27
|
+
model = WithValidationContext.new(name: 'short')
|
|
28
|
+
|
|
29
|
+
db.save(model, context: :custom)
|
|
30
|
+
|
|
31
|
+
expect(model.errors[:name]).to eq(["is too short (minimum is 10 characters)"])
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'uses a custom context on update when specified' do
|
|
35
|
+
model = WithValidationContext.new(name: 'initial name')
|
|
36
|
+
db.save!(model)
|
|
37
|
+
|
|
38
|
+
model.name = 'new'
|
|
39
|
+
db.save(model, context: :custom)
|
|
40
|
+
|
|
41
|
+
expect(model.errors[:name]).to eq(["is too short (minimum is 10 characters)"])
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context 'when calling save!' do
|
|
47
|
+
|
|
48
|
+
it 'uses the :create context on creation' do
|
|
49
|
+
model = WithValidationContext.new
|
|
50
|
+
|
|
51
|
+
expect do
|
|
52
|
+
db.save!(model)
|
|
53
|
+
end.to raise_error(CouchPotato::Database::ValidationsFailedError, /Name can't be blank/)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'uses the :update context on update' do
|
|
57
|
+
model = WithValidationContext.new(name: 'initial name')
|
|
58
|
+
db.save!(model)
|
|
59
|
+
|
|
60
|
+
model.name = 'new'
|
|
61
|
+
expect do
|
|
62
|
+
db.save!(model)
|
|
63
|
+
end.to raise_error(CouchPotato::Database::ValidationsFailedError, /Name is too short \(minimum is 5 characters\)/)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'uses a custom context on create when specified' do
|
|
67
|
+
model = WithValidationContext.new(name: 'short')
|
|
68
|
+
|
|
69
|
+
expect do
|
|
70
|
+
db.save!(model, context: :custom)
|
|
71
|
+
end.to raise_error(CouchPotato::Database::ValidationsFailedError, /Name is too short \(minimum is 10 characters\)/)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'uses a custom context on update when specified' do
|
|
75
|
+
model = WithValidationContext.new(name: 'initial name')
|
|
76
|
+
db.save!(model)
|
|
77
|
+
|
|
78
|
+
model.name = 'new'
|
|
79
|
+
expect do
|
|
80
|
+
db.save!(model, context: :custom)
|
|
81
|
+
end.to raise_error(CouchPotato::Database::ValidationsFailedError, /Name is too short \(minimum is 10 characters\)/)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: couch_potato
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.20.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alexander Lang
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-12-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activemodel
|
|
@@ -207,6 +207,7 @@ files:
|
|
|
207
207
|
- spec/unit/validation_spec.rb
|
|
208
208
|
- spec/unit/view_query_spec.rb
|
|
209
209
|
- spec/update_spec.rb
|
|
210
|
+
- spec/validation_context_spec.rb
|
|
210
211
|
- spec/view_updates_spec.rb
|
|
211
212
|
- spec/views_spec.rb
|
|
212
213
|
- vendor/pouchdb-collate/LICENSE
|
|
@@ -275,5 +276,6 @@ test_files:
|
|
|
275
276
|
- spec/unit/validation_spec.rb
|
|
276
277
|
- spec/unit/view_query_spec.rb
|
|
277
278
|
- spec/update_spec.rb
|
|
279
|
+
- spec/validation_context_spec.rb
|
|
278
280
|
- spec/view_updates_spec.rb
|
|
279
281
|
- spec/views_spec.rb
|