iry 0.4.0 → 0.5.1

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: 4e4fc1d3dfa1e63a0ac7c38443301f2635ac7d60866d5799a1a6a78b5cdb9326
4
- data.tar.gz: 7b4a3e8b2118dfb0788f15579e61ca35b1e32277cd571fb53e83c2905e23cc49
3
+ metadata.gz: 5ca6d5b931545ba2bb0b9f1e9e7ad77da308e7d0ffe8a64d1df2c1e6378cd1a7
4
+ data.tar.gz: 4747d18e4a249735907597277bad301e9177dffa5aa00e3410355be13d523683
5
5
  SHA512:
6
- metadata.gz: 27cc273db8893f605a6d3480305a0e575f214a4c88562a701b0ba1b00b4a98b004735f7f776428b246722c0a26706ba2681405028f0454658085cf562e94fd7b
7
- data.tar.gz: 01b82838cf8c8e02432fe038086fa3a96db7ff83a128e5e3ac1aacc5524e2e9a76c908f0af72e85eac19bbed6ccc0972718ba9f49e69ab5d81775fc508a946e6
6
+ metadata.gz: c2b72c6a64b044c606b3940181971a28fd90fdb1ba7859566adb9f5b7ac17f58aa46544908d06715dbc15105972ee0b272ac65d608dd06ee42fd829799c3ff95
7
+ data.tar.gz: 2f5c703a19785a8e7fc5689354c80b91d3d3658f00a031edbddad7ca06c36094959f494bbc157c8b40bce4fd3655fd37fa5769ec1fc02e6b7c74524118ebc37b
data/.yardopts CHANGED
@@ -1 +1 @@
1
- --no-private 'lib/**/*.rb' - 'README.md' 'CHANGELOG.md' VERSION LICENSE '.envrc.example' Gemfile 'Gemfile.lock' 'db/schema.pgsql' 'iry.gemspec'
1
+ --no-private 'lib/**/*.rb' - 'README.md' VERSION LICENSE '.envrc.example' Gemfile 'Gemfile.lock' 'db/schema.pgsql' 'iry.gemspec'
data/README.md CHANGED
@@ -39,6 +39,7 @@ Now one of the saving mechanisms can be used:
39
39
  - [`handle_constraints`](#handle_constraints)
40
40
  - [`save`](#save)
41
41
  - [`save!`](#save!)
42
+ - [`destroy`](#destroy)
42
43
 
43
44
  When saving a new `User` record or updating it, in case constraint exceptions are raised, these will be rescued and
44
45
  validation errors will be applied to the record, like in the following example:
@@ -139,6 +140,12 @@ errors will be added to `errors`.
139
140
  Acts the same as `ActiveRecord::Base#save!`, accepting the same arguments and returning the same values.
140
141
  In addition, it will raise `Iry::ConstraintViolation` when constraint violations are detected.
141
142
 
143
+ ### [`destroy`](https://rubydoc.info/gems/iry/Iry.destroy)
144
+
145
+ Acts the same as `ActiveRecord::Base#destroy`.
146
+ In addition, it will return `false` if a constraint violation of the tracked constraints is detected and validation
147
+ errors will be added to `errors`.
148
+
142
149
  ## Limitations
143
150
 
144
151
  - `valid?` will not check for constraints. If calling `valid?` right after a `save` operation, keep in mind `errors`
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.0
1
+ 0.5.1
@@ -13,7 +13,7 @@ module Iry
13
13
  exclusion\sconstraint|
14
14
  foreign\skey\sconstraint
15
15
  )
16
- \s"(.+)"
16
+ \s"([^"]+)"
17
17
  }x
18
18
 
19
19
  # When true, the handler is able to handle this exception, representing a constraint error in PostgreSQL.
data/lib/iry/patch.rb ADDED
@@ -0,0 +1,13 @@
1
+ module Iry
2
+ # Overrides private API method {ActiveRecord#create_or_update} to handle
3
+ # constraints and attach errors to the including model
4
+ module Patch
5
+ # Takes attributes as named arguments
6
+ # @return [Boolean] true if successful
7
+ def create_or_update(...)
8
+ result = false
9
+ Iry.handle_constraints!(self) { result = super }
10
+ result
11
+ end
12
+ end
13
+ end
data/lib/iry.rb CHANGED
@@ -11,6 +11,7 @@ require_relative "iry/constraint/check"
11
11
  require_relative "iry/constraint/exclusion"
12
12
  require_relative "iry/constraint/foreign_key"
13
13
  require_relative "iry/constraint/unique"
14
+ require_relative "iry/patch"
14
15
 
15
16
  # Entrypoint of constraint validation, include in a class inheriting {ActiveRecord::Base} and the following class-level
16
17
  # methods will be available:
@@ -49,6 +50,10 @@ module Iry
49
50
  # @return [Handlers::Model]
50
51
  end
51
52
 
53
+ class StatementInvalid < ActiveRecord::StatementInvalid
54
+ include Error
55
+ end
56
+
52
57
  # @param klass [Module]
53
58
  # @return [void]
54
59
  # @private
@@ -58,6 +63,7 @@ module Iry
58
63
  class_attribute(:constraints)
59
64
  self.constraints = {}
60
65
  extend(Iry::Macros)
66
+ include(Iry::Patch)
61
67
  end
62
68
  end
63
69
 
@@ -82,6 +88,18 @@ module Iry
82
88
  # result #=> nil
83
89
  # fail_user.errors.details.fetch(:email) #=> [{error: :taken}]
84
90
  def self.handle_constraints(model, &block)
91
+ handle_constraints!(model, &block)
92
+ rescue StatementInvalid
93
+ return nil
94
+ end
95
+
96
+ # Executes block and in case of constraints violations on `model`, block is
97
+ # halted, errors are appended to `model` and {StatementInvalid} is raised
98
+ # @param model [Handlers::Model] model object for which constraints should be
99
+ # monitored and for which errors should be added to
100
+ # @yield block must perform the save operation, usually with `save`
101
+ # @return [Handlers::Model] returns `model` parameter
102
+ def self.handle_constraints!(model, &block)
85
103
  raise ArgumentError, "Block required" if block.nil?
86
104
 
87
105
  block.()
@@ -101,7 +119,7 @@ module Iry
101
119
  raise
102
120
  end
103
121
 
104
- return nil
122
+ raise StatementInvalid.new(err.message, sql: err.sql, binds: err.binds)
105
123
  end
106
124
 
107
125
  # Similar to {ActiveRecord::Base#save} but in case of constraint violations,
@@ -141,4 +159,18 @@ module Iry
141
159
 
142
160
  raise ConstraintViolation.new(model)
143
161
  end
162
+
163
+ # Similar to {ActiveRecord::Base#destroy} but in case of constraint
164
+ # violations, `false` is returned and `errors` are populated.
165
+ # @param model [Handlers::Model] model to destroy
166
+ # @return [Handlers::Model] the destroyed model
167
+ def self.destroy(model)
168
+ constraint_result = handle_constraints(model) { model.destroy }
169
+
170
+ if constraint_result.nil?
171
+ return false
172
+ end
173
+
174
+ return constraint_result
175
+ end
144
176
  end
data/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "iry",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "iry",
9
- "version": "0.4.0",
9
+ "version": "0.5.1",
10
10
  "license": "MIT",
11
11
  "devDependencies": {
12
12
  "conventional-changelog-cli": ">= 3.0.0",
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iry",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "description": "Transform database constraint errors into activerecord validation errors",
5
5
  "private": true,
6
6
  "main": "index.js",
data/rbi/iry.rbi CHANGED
@@ -57,6 +57,15 @@ module Iry
57
57
  sig { params(model: Handlers::Model, block: T.untyped).void }
58
58
  def self.handle_constraints(model, &block); end
59
59
 
60
+ # Executes block and in case of constraints violations on `model`, block is
61
+ # halted, errors are appended to `model` and {StatementInvalid} is raised
62
+ #
63
+ # _@param_ `model` — model object for which constraints should be monitored and for which errors should be added to
64
+ #
65
+ # _@return_ — returns `model` parameter
66
+ sig { params(model: Handlers::Model, block: T.untyped).returns(Handlers::Model) }
67
+ def self.handle_constraints!(model, &block); end
68
+
60
69
  # Similar to {ActiveRecord::Base#save} but in case of constraint violations,
61
70
  # `false` is returned and `errors` are populated.
62
71
  # Aside from `model`, it takes the same arguments as
@@ -77,6 +86,15 @@ module Iry
77
86
  sig { params(model: Handlers::Model).returns(T::Boolean) }
78
87
  def self.save!(model); end
79
88
 
89
+ # Similar to {ActiveRecord::Base#destroy} but in case of constraint
90
+ # violations, `false` is returned and `errors` are populated.
91
+ #
92
+ # _@param_ `model` — model to destroy
93
+ #
94
+ # _@return_ — the destroyed model
95
+ sig { params(model: Handlers::Model).returns(Handlers::Model) }
96
+ def self.destroy(model); end
97
+
80
98
  # Included in all exceptions triggered by Iry, this allows to rescue any
81
99
  # gem-related exception by rescuing {Iry::Error}
82
100
  module Error
@@ -88,6 +106,20 @@ module Iry
88
106
  include Iry::Error
89
107
  end
90
108
 
109
+ class StatementInvalid < ActiveRecord::StatementInvalid
110
+ include Iry::Error
111
+ end
112
+
113
+ # Overrides private API method {ActiveRecord#create_or_update} to handle
114
+ # constraints and attach errors to the including model
115
+ module Patch
116
+ # Takes attributes as named arguments
117
+ #
118
+ # _@return_ — true if successful
119
+ sig { returns(T::Boolean) }
120
+ def create_or_update; end
121
+ end
122
+
91
123
  # Class-level methods available to classes executing `include Iry`
92
124
  module Macros
93
125
  # Constraints by name
@@ -207,7 +239,7 @@ module Iry
207
239
  exclusion\sconstraint|
208
240
  foreign\skey\sconstraint
209
241
  )
210
- \s"(.+)"
242
+ \s"([^"]+)"
211
243
  }x, T.untyped)
212
244
 
213
245
  # sord warn - ActiveRecord::StatementInvalid wasn't able to be resolved to a constant in this project
data/sig/iry.rbs CHANGED
@@ -53,6 +53,14 @@ module Iry
53
53
  # ```
54
54
  def self.handle_constraints: (Handlers::Model model) -> void
55
55
 
56
+ # Executes block and in case of constraints violations on `model`, block is
57
+ # halted, errors are appended to `model` and {StatementInvalid} is raised
58
+ #
59
+ # _@param_ `model` — model object for which constraints should be monitored and for which errors should be added to
60
+ #
61
+ # _@return_ — returns `model` parameter
62
+ def self.handle_constraints!: (Handlers::Model model) -> Handlers::Model
63
+
56
64
  # Similar to {ActiveRecord::Base#save} but in case of constraint violations,
57
65
  # `false` is returned and `errors` are populated.
58
66
  # Aside from `model`, it takes the same arguments as
@@ -71,6 +79,14 @@ module Iry
71
79
  # _@param_ `model` — model to save
72
80
  def self.save!: (Handlers::Model model) -> bool
73
81
 
82
+ # Similar to {ActiveRecord::Base#destroy} but in case of constraint
83
+ # violations, `false` is returned and `errors` are populated.
84
+ #
85
+ # _@param_ `model` — model to destroy
86
+ #
87
+ # _@return_ — the destroyed model
88
+ def self.destroy: (Handlers::Model model) -> Handlers::Model
89
+
74
90
  # Included in all exceptions triggered by Iry, this allows to rescue any
75
91
  # gem-related exception by rescuing {Iry::Error}
76
92
  module Error
@@ -82,6 +98,19 @@ module Iry
82
98
  include Iry::Error
83
99
  end
84
100
 
101
+ class StatementInvalid < ActiveRecord::StatementInvalid
102
+ include Iry::Error
103
+ end
104
+
105
+ # Overrides private API method {ActiveRecord#create_or_update} to handle
106
+ # constraints and attach errors to the including model
107
+ module Patch
108
+ # Takes attributes as named arguments
109
+ #
110
+ # _@return_ — true if successful
111
+ def create_or_update: () -> bool
112
+ end
113
+
85
114
  # Class-level methods available to classes executing `include Iry`
86
115
  module Macros
87
116
  # Constraints by name
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Francesco Belladonna
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-07-09 00:00:00.000000000 Z
11
+ date: 2023-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -89,7 +89,6 @@ extra_rdoc_files: []
89
89
  files:
90
90
  - ".envrc.example"
91
91
  - ".yardopts"
92
- - CHANGELOG.md
93
92
  - LICENSE
94
93
  - README.md
95
94
  - Rakefile
@@ -107,6 +106,7 @@ files:
107
106
  - lib/iry/handlers/null.rb
108
107
  - lib/iry/handlers/pg.rb
109
108
  - lib/iry/macros.rb
109
+ - lib/iry/patch.rb
110
110
  - lib/iry/version.rb
111
111
  - package-lock.json
112
112
  - package.json
@@ -122,7 +122,6 @@ metadata:
122
122
  allowed_push_host: https://rubygems.org/
123
123
  homepage_uri: https://github.com/Fire-Dragon-DoL/iry
124
124
  source_code_uri: https://github.com/Fire-Dragon-DoL/iry
125
- changelog_uri: https://github.com/Fire-Dragon-DoL/iry/blob/main/CHANGELOG.md
126
125
  post_install_message:
127
126
  rdoc_options: []
128
127
  require_paths:
data/CHANGELOG.md DELETED
@@ -1,15 +0,0 @@
1
- # [0.2.0](https://github.com/Fire-Dragon-DoL/iry/compare/8a133c2c19b99881619a9e1c7c11076030755f66...v0.2.0) (2023-07-08)
2
-
3
-
4
- ### Features
5
-
6
- * **constraints:** check constraint is present ([d0cc380](https://github.com/Fire-Dragon-DoL/iry/commit/d0cc3803fdcda45df964f6431890f8831d3641e5))
7
- * **constraints:** exclusion constraint is present ([1894e85](https://github.com/Fire-Dragon-DoL/iry/commit/1894e85bfa11e272be9b5f0f8efc170f7ce57a48))
8
- * **constraints:** foreign key constraint is present ([e637b06](https://github.com/Fire-Dragon-DoL/iry/commit/e637b0603bb6fd34e2732426544fc31904bb5409))
9
- * **deps:** dependency surface is reduced ([2dfc595](https://github.com/Fire-Dragon-DoL/iry/commit/2dfc595ebd221aedb072398e1ace8460208d06ac))
10
- * **project:** setup ([8a133c2](https://github.com/Fire-Dragon-DoL/iry/commit/8a133c2c19b99881619a9e1c7c11076030755f66))
11
- * **ruby:** version is forced to >= 2.7 ([9b20ed8](https://github.com/Fire-Dragon-DoL/iry/commit/9b20ed8ec0ae2a9906bdefe28cf674d4700f4d67))
12
- * **unique-constraint:** test is implemented ([c4266b9](https://github.com/Fire-Dragon-DoL/iry/commit/c4266b910757b6adef18db41dfa5dfd9353c1037))
13
-
14
-
15
-