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 +4 -4
- data/CHANGELOG.md +9 -10
- data/VERSION +1 -1
- data/lib/iry/callbacks.rb +5 -1
- data/lib/iry/macros.rb +3 -5
- data/lib/iry.rb +75 -3
- data/package-lock.json +2 -2
- data/package.json +3 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1cabc0965e3b746552dee09d6fcf0356bb0f166114e3cb9d696c00c033742016
|
4
|
+
data.tar.gz: 0171d5388f8a7ee89d942e1ea959e2e309f3ef15fc869dba804dba8e6de0877f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef0954dca71dbdeacd8588256939faa6a18b16ff85d1b913980c23e5058c54ceaf946959de3bbb0b9f421b5b5b3f57dea5d4d001295d6e2ad17fbfeda688771d
|
7
|
+
data.tar.gz: cd3117ad1717f98fbe96d823920a25742aca1a3f10948f60ae47f9567a31c7e55633d7b2dc3ee8d151cb60e7416bd9cdb840211e8e81cd44d63ced15b199bdc1
|
data/CHANGELOG.md
CHANGED
@@ -1,16 +1,15 @@
|
|
1
|
-
|
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 ([
|
11
|
-
* **constraints:** exclusion constraint is present ([
|
12
|
-
* **constraints:** foreign key constraint is present ([
|
13
|
-
* **deps:** dependency surface is reduced ([
|
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 ([
|
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.
|
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
|
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
|
-
#
|
5
|
-
#
|
6
|
-
|
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.
|
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.
|
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.
|
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.
|
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-
|
11
|
+
date: 2023-07-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|