iry 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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