iry 0.2.0 → 0.3.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: e650372034f89b6bd6d8187f83f7e54ec43a9fa9cf69f4c1ec07ee091b07063c
4
- data.tar.gz: 0dad363e7219745a1f92a0af6fe2348a98029f3740cd6031d46535a39c742dd2
3
+ metadata.gz: 1cabc0965e3b746552dee09d6fcf0356bb0f166114e3cb9d696c00c033742016
4
+ data.tar.gz: 0171d5388f8a7ee89d942e1ea959e2e309f3ef15fc869dba804dba8e6de0877f
5
5
  SHA512:
6
- metadata.gz: 460f2ebab05bbe7271634f5a7d5cb0ae6644d5f53982e3bec6ac0f8c9f6745ca5c8e3aea3f931649112a2b1641d411c788f9fc3aba643ae03c9e4f50b85784b7
7
- data.tar.gz: 17a3e4033f3a731e110706db24b6b71f95b3059b7b113299cf6c651001e7f309b2402b867b7a974f9532ba89a7f499cb7533a2eebc8217bb693513923e8713af
6
+ metadata.gz: ef0954dca71dbdeacd8588256939faa6a18b16ff85d1b913980c23e5058c54ceaf946959de3bbb0b9f421b5b5b3f57dea5d4d001295d6e2ad17fbfeda688771d
7
+ data.tar.gz: cd3117ad1717f98fbe96d823920a25742aca1a3f10948f60ae47f9567a31c7e55633d7b2dc3ee8d151cb60e7416bd9cdb840211e8e81cd44d63ced15b199bdc1
data/CHANGELOG.md CHANGED
@@ -1,16 +1,15 @@
1
- ## [0.1.1](https://github.com/Fire-Dragon-DoL/iry/compare/v0.1.0...v0.1.1) (2023-07-07)
2
-
3
-
4
-
5
- # [0.1.0](https://github.com/Fire-Dragon-DoL/iry/compare/8a133c2c19b99881619a9e1c7c11076030755f66...v0.1.0) (2023-07-07)
1
+ # [0.2.0](https://github.com/Fire-Dragon-DoL/iry/compare/8a133c2c19b99881619a9e1c7c11076030755f66...v0.2.0) (2023-07-08)
6
2
 
7
3
 
8
4
  ### Features
9
5
 
10
- * **constraints:** check constraint is present ([2723ad7](https://github.com/Fire-Dragon-DoL/iry/commit/2723ad70d7dbb4cea4b4c6e92ce59627fae64c27))
11
- * **constraints:** exclusion constraint is present ([bdb904a](https://github.com/Fire-Dragon-DoL/iry/commit/bdb904a80dd1f6b1960f2b8378490cc192deb83e))
12
- * **constraints:** foreign key constraint is present ([efed498](https://github.com/Fire-Dragon-DoL/iry/commit/efed4986a10b40c77dcd063d8801eb77d605d807))
13
- * **deps:** dependency surface is reduced ([ff4af7e](https://github.com/Fire-Dragon-DoL/iry/commit/ff4af7e365537e30a0d95bfdee84e681f54c155a))
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))
14
10
  * **project:** setup ([8a133c2](https://github.com/Fire-Dragon-DoL/iry/commit/8a133c2c19b99881619a9e1c7c11076030755f66))
15
- * **ruby:** version is forced to >= 2.7 ([f386ce6](https://github.com/Fire-Dragon-DoL/iry/commit/f386ce6db3aab7399b71a15bfed8228884a82f16))
11
+ * **ruby:** version is forced to >= 2.7 ([9b20ed8](https://github.com/Fire-Dragon-DoL/iry/commit/9b20ed8ec0ae2a9906bdefe28cf674d4700f4d67))
16
12
  * **unique-constraint:** test is implemented ([c4266b9](https://github.com/Fire-Dragon-DoL/iry/commit/c4266b910757b6adef18db41dfa5dfd9353c1037))
13
+
14
+
15
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
data/lib/iry/callbacks.rb CHANGED
@@ -19,7 +19,11 @@ module Iry
19
19
 
20
20
  is_handled = handler.handle(err, model)
21
21
 
22
- if !is_handled
22
+ if is_handled
23
+ # Rolling back allows to keep using SQL in other callbacks, which
24
+ # otherwise would raise PG::InFailedSqlTransaction
25
+ raise ActiveRecord::Rollback
26
+ else
23
27
  raise
24
28
  end
25
29
  end
data/lib/iry/macros.rb CHANGED
@@ -1,11 +1,9 @@
1
1
  module Iry
2
2
  # Class-level methods available to classes executing `include Iry`
3
3
  module Macros
4
- # Constraints by name
5
- # @return [{String => Constraint}]
6
- def constraints
7
- @constraints ||= {}
8
- end
4
+ # @!method constraints
5
+ # Constraints by name
6
+ # @return [{String => Constraint}]
9
7
 
10
8
  # Tracks check constraint for the given key and convert constraint errors into validation errors
11
9
  # @param key [Symbol] key to apply validation errors to
data/lib/iry.rb CHANGED
@@ -32,15 +32,87 @@ require_relative "iry/constraint/unique"
32
32
  # fail_user = User.create(email: "user@example.com")
33
33
  # fail_user.errors.details.fetch(:email) #=> [{error: :taken}]
34
34
  module Iry
35
+ # Raised when constraint errors have been violated and have been converted to
36
+ # model errors
37
+ class RecordInvalid < ActiveRecord::RecordInvalid
38
+ end
39
+
35
40
  # @param klass [Module]
36
41
  # @return [void]
37
42
  # @private
38
43
  def self.included(klass)
39
44
  klass.class_eval do
45
+ # From activesupport
46
+ class_attribute(:constraints)
47
+ self.constraints = {}
40
48
  extend(Iry::Macros)
41
- # Prepend ensures around save happens before all around_save callbacks
42
- # adding the errors as soon as possible
43
- around_save(Iry::Callbacks, prepend: true)
44
49
  end
45
50
  end
51
+
52
+ # Executes block and in case of constraints violations on `model`, block is
53
+ # halted and errors are appended to `model`
54
+ # @param model [Handlers::Model] model object for which constraints should be
55
+ # monitored and for which errors should be added to
56
+ # @yield block must perform the save operation, usually with `save`
57
+ # @return [nil, Handlers::Model] the `model` or `nil` if a a constraint is
58
+ # violated
59
+ def self.handle_constraints(model, &block)
60
+ raise ArgumentError, "Block required" if block.nil?
61
+
62
+ block.()
63
+
64
+ return model
65
+ rescue ActiveRecord::StatementInvalid => err
66
+ handler = Handlers::Null
67
+ case
68
+ when Handlers::PG.handle?(err)
69
+ handler = Handlers::PG
70
+ end
71
+
72
+ is_handled = handler.handle(err, model)
73
+
74
+ if !is_handled
75
+ raise
76
+ end
77
+
78
+ return nil
79
+ end
80
+
81
+ # Similar to {ActiveRecord::Base#save} but in case of constraint violations,
82
+ # `false` is returned and `errors` are populated.
83
+ # Aside from `model`, it takes the same arguments as
84
+ # {ActiveRecord::Base#save}
85
+ # @param model [Handlers::Model] model to save
86
+ # @return [Boolean] `true` if successful
87
+ def self.save(model, ...)
88
+ success = nil
89
+ constraint_model = handle_constraints(model) { success = model.save(...) }
90
+
91
+ if constraint_model
92
+ return success
93
+ end
94
+
95
+ return false
96
+ end
97
+
98
+ # Similar to {ActiveRecord::Base#save!} but in case of constraint violations,
99
+ # it raises {RecordInvalid} and `errors` are populated.
100
+ # Aside from `model`, it takes the same arguments as
101
+ # {ActiveRecord::Base#save!}
102
+ # @param model [Handlers::Model] model to save
103
+ # @return [true]
104
+ # @raise [RecordInvalid] {RecordInvalid} inherits from
105
+ # {ActiveRecord::RecordInvalid} but it's triggered only when a constraint
106
+ # violation happens
107
+ # @raise [ActiveRecord::RecordInvalid] triggered when a validation error is
108
+ # raised, but not a constraint violation
109
+ def self.save!(model, ...)
110
+ constraint_model = handle_constraints(model) { model.save!(...) }
111
+
112
+ if constraint_model
113
+ return true
114
+ end
115
+
116
+ raise RecordInvalid.new(model)
117
+ end
46
118
  end
data/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "iry",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "iry",
9
- "version": "0.2.0",
9
+ "version": "0.3.0",
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.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Transform database constraint errors into activerecord validation errors",
5
5
  "private": true,
6
6
  "main": "index.js",
@@ -10,7 +10,8 @@
10
10
  "test": "test"
11
11
  },
12
12
  "scripts": {
13
- "test": "echo \"Error: no test specified\" && exit 1"
13
+ "test": "echo \"Error: no test specified\" && exit 1",
14
+ "version-get": "echo \"$npm_package_version\""
14
15
  },
15
16
  "repository": {
16
17
  "type": "git",
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.2.0
4
+ version: 0.3.0
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-08 00:00:00.000000000 Z
11
+ date: 2023-07-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord