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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e1d161e4bd65577a3de846d945bc5787dbdacdec35c7e38f3129e8108cfa5a3
4
- data.tar.gz: 967bcb265ed7886130a9fa79acb51a2f4420ec16e45ac7373d1b39a4895951c0
3
+ metadata.gz: 3550e8fe5b60fb064f2960a62313ee43e41e28c980c7c7d395d6c252fdb4fa20
4
+ data.tar.gz: 4aff0328b8e0e2162793c8b7f81643a5a3a43b703a64b00c57f044c12aac0ab0
5
5
  SHA512:
6
- metadata.gz: f5b282eda9e2c8bcaf1ad191cd5f5f867dfc2ef406a6db2f079a5882b198149ef416e07ef3a3fd5ed7c82bbd5ddb9f82243cce16509dce0f8b7d7fa8d9e1768a
7
- data.tar.gz: 713b759678703c0bbdf935e17405dd07f62f0b1e2d92a1afed81bde89620c16514320088887f275af8fcfc9114684f754687ed5306b1f8a52ca1bca3888c2407
6
+ metadata.gz: 676096f6f62795015a3bb26b6fe27689eda09aacb59f05c1f181a2922bc968fd762a9571ef02085425071212cf3ee1c688d36caaf06ee68dafe134d6bf9c04ae
7
+ data.tar.gz: 49582697b2508b97fc73a9a1a0590e6882f138577ea5ab6492746a61ab654b74170830cf9c61b4de1b36f002bd344b0b193f903dec6dc78e10f6a3f5d2c7c9d1
@@ -26,7 +26,7 @@ jobs:
26
26
  steps:
27
27
  - uses: actions/checkout@v4
28
28
  - name: Set up CouchDB
29
- uses: cobot/couchdb-action@v5
29
+ uses: cobot/couchdb-action@v5.0.1
30
30
  with:
31
31
  couchdb-version: "2.3.1"
32
32
  - name: Set up Ruby
data/CHANGES.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## Changes
2
2
 
3
+ # 1.20.0
4
+
5
+ - add passing validation context to save methods
6
+
3
7
  # 1.19.2
4
8
 
5
9
  - fix 404/409 error when querying single design doc with `digest_view_names` enabled
@@ -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, validate = true, retries = 0, &block)
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, validate)
118
+ save_document_without_conflict_handling(document, options)
116
119
  rescue CouchRest::Conflict
117
120
  if block
118
- handle_write_conflict document, validate, retries, &block
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, validate, retries, &block)
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, validate, retries + 1, &block
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, validate = true)
320
+ def save_document_without_conflict_handling(document, options = {})
318
321
  if document.new?
319
- create_document(document, validate)
322
+ create_document(document, options)
320
323
  else
321
- update_document(document, validate)
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, validate)
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 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
+
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) }
@@ -1,4 +1,4 @@
1
1
  module CouchPotato
2
- VERSION = '1.19.2'.freeze
2
+ VERSION = '1.20.0'.freeze
3
3
  RSPEC_VERSION = '4.2.0'.freeze
4
4
  end
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.19.2
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-06-08 00:00:00.000000000 Z
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