iry 0.5.1 → 0.6.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/VERSION +1 -1
- data/lib/iry/constraint/check.rb +1 -1
- data/lib/iry/constraint/exclusion.rb +1 -1
- data/lib/iry/constraint/foreign_key.rb +1 -1
- data/lib/iry/constraint/unique.rb +1 -1
- data/lib/iry/constraint.rb +1 -1
- data/lib/iry/handlers/null.rb +2 -2
- data/lib/iry/handlers/pg.rb +5 -5
- data/lib/iry/handlers.rb +2 -1
- data/lib/iry/patch.rb +1 -1
- data/lib/iry/transform_constraints.rb +139 -0
- data/lib/iry.rb +26 -46
- data/package-lock.json +2 -2
- data/package.json +1 -1
- data/rbi/iry.rbi +117 -10
- data/sig/iry.rbs +100 -10
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 592290e30f1db830217241ebde319fbf952ee459ac05c3bc1e87b4b47a73e143
|
|
4
|
+
data.tar.gz: '09cabb7faf8e78a91e7d2443bdfd5466d7e8f63bc90fcfeb2abdb72f93bd79bf'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 915d87f39809daa1a0a76ea66c4718e20afe6dbef4ced1853df47e9457927a464a06204cd4c0abd71dad861d8df6f23c974b2a75796ff7136b17f94875fb36ae
|
|
7
|
+
data.tar.gz: f8b10f525eab24f478a3bb6ee2c1039258b65d532eb5475d584f68bec23cf6c2e305e47033b4621dfe49be563da584c488683905d12c9abf529c07ec194d46bc
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.6.0
|
data/lib/iry/constraint/check.rb
CHANGED
data/lib/iry/constraint.rb
CHANGED
data/lib/iry/handlers/null.rb
CHANGED
|
@@ -15,9 +15,9 @@ module Iry
|
|
|
15
15
|
# Return always false, failing to handle any constraint
|
|
16
16
|
# @param err [ActiveRecord::StatementInvalid]
|
|
17
17
|
# @param model [Model] should inherit {ActiveRecord::Base} and`include Iry` to match the interface
|
|
18
|
-
# @return [
|
|
18
|
+
# @return [nil, ActiveModel::Error]
|
|
19
19
|
def handle(err, model)
|
|
20
|
-
return
|
|
20
|
+
return nil
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
end
|
data/lib/iry/handlers/pg.rb
CHANGED
|
@@ -36,7 +36,9 @@ module Iry
|
|
|
36
36
|
# Appends constraint errors as model errors
|
|
37
37
|
# @param err [ActiveRecord::StatementInvalid]
|
|
38
38
|
# @param model [Model] should inherit {ActiveRecord::Base} and`include Iry` to match the interface
|
|
39
|
-
# @return [
|
|
39
|
+
# @return [nil, ActiveModel::Error] if handled constraint, returns the
|
|
40
|
+
# error attached to the model. If constraint wasn't handled or handling
|
|
41
|
+
# failed, `nil` is returned
|
|
40
42
|
def handle(err, model)
|
|
41
43
|
pgerr = err.cause
|
|
42
44
|
constraint_name_msg = pgerr.result.error_field(::PG::Constants::PG_DIAG_MESSAGE_PRIMARY)
|
|
@@ -44,12 +46,10 @@ module Iry
|
|
|
44
46
|
constraint_name = match[1]
|
|
45
47
|
constraint = model.class.constraints[constraint_name]
|
|
46
48
|
if constraint.nil?
|
|
47
|
-
return
|
|
49
|
+
return nil
|
|
48
50
|
end
|
|
49
51
|
|
|
50
|
-
constraint.apply(model)
|
|
51
|
-
|
|
52
|
-
return true
|
|
52
|
+
return constraint.apply(model)
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
end
|
data/lib/iry/handlers.rb
CHANGED
|
@@ -12,7 +12,8 @@ module Iry
|
|
|
12
12
|
# @abstract
|
|
13
13
|
# @param err [ActiveRecord::StatementInvalid] possible constraint error to handle
|
|
14
14
|
# @param model [Model]
|
|
15
|
-
# @return [
|
|
15
|
+
# @return [nil, ActiveModel::Error] `nil` if couldn't handle the error,
|
|
16
|
+
# otherwise the {ActiveModel::Error} added to the model
|
|
16
17
|
def handle(err, model)
|
|
17
18
|
end
|
|
18
19
|
end
|
data/lib/iry/patch.rb
CHANGED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
module Iry
|
|
2
|
+
# Implementation of {Iry} methods, helps ensuring the main module focus on
|
|
3
|
+
# documentation
|
|
4
|
+
module TransformConstraints
|
|
5
|
+
extend self
|
|
6
|
+
|
|
7
|
+
# @param model [Handlers::Model]
|
|
8
|
+
# @yield
|
|
9
|
+
# @return [nil, Handlers::Model]
|
|
10
|
+
def handle_constraints(model, &block)
|
|
11
|
+
handle_constraints!(model, &block)
|
|
12
|
+
rescue StatementInvalid
|
|
13
|
+
return nil
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @param model [Handlers::Model]
|
|
17
|
+
# @yield
|
|
18
|
+
# @return [Handlers::Model]
|
|
19
|
+
def handle_constraints!(model, &block)
|
|
20
|
+
# Allows checking if Iry has been activated (handling).
|
|
21
|
+
# Number is used to support nested handle_constraints!
|
|
22
|
+
Thread.current[:iry] ||= 0
|
|
23
|
+
Thread.current[:iry] += 1
|
|
24
|
+
|
|
25
|
+
nested_constraints!(model, &block)
|
|
26
|
+
rescue StatementInvalid => err
|
|
27
|
+
# Imports errors from "nested" models back into the parent, to ensure
|
|
28
|
+
# `errors` is populated and the record is considered invalid
|
|
29
|
+
|
|
30
|
+
# Skip if error has been added to the same object being handled
|
|
31
|
+
if err.record.object_id == model.object_id
|
|
32
|
+
raise
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Adds the error only if it hasn't been added already
|
|
36
|
+
already_imported = model
|
|
37
|
+
.errors
|
|
38
|
+
.each
|
|
39
|
+
.lazy
|
|
40
|
+
.select { |ae| ae.respond_to?(:inner_error) }
|
|
41
|
+
.map { |ae| ae.inner_error }
|
|
42
|
+
.include?(err.error)
|
|
43
|
+
if !already_imported
|
|
44
|
+
model.errors.import(err.error)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
raise
|
|
48
|
+
ensure
|
|
49
|
+
# "Pop" handle_constraints! usage, when 0, no constraint handling should
|
|
50
|
+
# happen
|
|
51
|
+
Thread.current[:iry] -= 1
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Tracks constraints of models saved as a consequence of saving another
|
|
55
|
+
# model. This usually represents a situation of model using
|
|
56
|
+
# `accepts_nested_attributes_for`
|
|
57
|
+
# @param model [Handlers::Model]
|
|
58
|
+
# @yield
|
|
59
|
+
# @return [Handlers::Model]
|
|
60
|
+
# @private
|
|
61
|
+
def nested_constraints!(model, &block)
|
|
62
|
+
raise ArgumentError, "Block required" if block.nil?
|
|
63
|
+
|
|
64
|
+
block.()
|
|
65
|
+
|
|
66
|
+
return model
|
|
67
|
+
rescue ActiveRecord::StatementInvalid => err
|
|
68
|
+
# Exit immediately if Iry hasn't been activated
|
|
69
|
+
if Thread.current[:iry].nil? || Thread.current[:iry] == 0
|
|
70
|
+
raise
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Exception might be an unknown constraint that is not handled by Iry
|
|
74
|
+
# yet. If that's the case, Null handler will ensure that everything
|
|
75
|
+
# proceeds as if Iry wasn't involved
|
|
76
|
+
handler = Handlers::Null
|
|
77
|
+
case
|
|
78
|
+
when Handlers::PG.handle?(err)
|
|
79
|
+
handler = Handlers::PG
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
model_error = handler.handle(err, model)
|
|
83
|
+
|
|
84
|
+
# This constraint is not handled by Iry and should raise normally
|
|
85
|
+
if model_error.nil?
|
|
86
|
+
raise
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
raise(
|
|
90
|
+
StatementInvalid.new(
|
|
91
|
+
err.message,
|
|
92
|
+
sql: err.sql,
|
|
93
|
+
binds: err.binds,
|
|
94
|
+
record: model,
|
|
95
|
+
error: model_error
|
|
96
|
+
)
|
|
97
|
+
)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# @param model [Handlers::Model]
|
|
101
|
+
# @return [Boolean]
|
|
102
|
+
def save(model, ...)
|
|
103
|
+
success = nil
|
|
104
|
+
constraint_model = handle_constraints(model) { success = model.save(...) }
|
|
105
|
+
|
|
106
|
+
if constraint_model
|
|
107
|
+
return success
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
return false
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# @param model [Handlers::Model]
|
|
114
|
+
# @return [true]
|
|
115
|
+
# @raise [ConstraintViolation]
|
|
116
|
+
# @raise [ActiveRecord::RecordInvalid]
|
|
117
|
+
def save!(model, ...)
|
|
118
|
+
constraint_model = handle_constraints(model) { model.save!(...) }
|
|
119
|
+
|
|
120
|
+
if constraint_model
|
|
121
|
+
return true
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
raise ConstraintViolation.new(model)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# @param model [Handlers::Model]
|
|
128
|
+
# @return [Handlers::Model]
|
|
129
|
+
def destroy(model)
|
|
130
|
+
constraint_result = handle_constraints(model) { model.destroy }
|
|
131
|
+
|
|
132
|
+
if constraint_result.nil?
|
|
133
|
+
return false
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
return constraint_result
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
data/lib/iry.rb
CHANGED
|
@@ -12,6 +12,7 @@ require_relative "iry/constraint/exclusion"
|
|
|
12
12
|
require_relative "iry/constraint/foreign_key"
|
|
13
13
|
require_relative "iry/constraint/unique"
|
|
14
14
|
require_relative "iry/patch"
|
|
15
|
+
require_relative "iry/transform_constraints"
|
|
15
16
|
|
|
16
17
|
# Entrypoint of constraint validation, include in a class inheriting {ActiveRecord::Base} and the following class-level
|
|
17
18
|
# methods will be available:
|
|
@@ -40,7 +41,8 @@ module Iry
|
|
|
40
41
|
end
|
|
41
42
|
|
|
42
43
|
# Raised when constraints have been violated and have been converted to
|
|
43
|
-
# model errors
|
|
44
|
+
# model errors, on {ActiveRecord::Base#save!} calls, to simulate a behavior
|
|
45
|
+
# similar to {ActiveRecord::RecordInvalid} when it's raised
|
|
44
46
|
class ConstraintViolation < ActiveRecord::RecordInvalid
|
|
45
47
|
include Error
|
|
46
48
|
|
|
@@ -50,8 +52,26 @@ module Iry
|
|
|
50
52
|
# @return [Handlers::Model]
|
|
51
53
|
end
|
|
52
54
|
|
|
55
|
+
# Raised when constraints errors happen and go through Iry, even if these
|
|
56
|
+
# are not handled. This class inherits from {ActiveRecord::StatementInvalid}
|
|
57
|
+
# to maximize compatibility with existing code
|
|
53
58
|
class StatementInvalid < ActiveRecord::StatementInvalid
|
|
54
59
|
include Error
|
|
60
|
+
|
|
61
|
+
# @return [Handlers::Model] model affected by the constraint violation
|
|
62
|
+
attr_reader :record
|
|
63
|
+
# @return [ActiveModel::Error] error attached to the `record` for the
|
|
64
|
+
# constraint violation
|
|
65
|
+
attr_reader :error
|
|
66
|
+
|
|
67
|
+
# @param message [nil, String]
|
|
68
|
+
# @param record [Handlers::Model]
|
|
69
|
+
# @param error [ActiveModel::Error]
|
|
70
|
+
def initialize(message = nil, record:, error:, **kwargs)
|
|
71
|
+
@record = record
|
|
72
|
+
@error = error
|
|
73
|
+
super(message, **kwargs)
|
|
74
|
+
end
|
|
55
75
|
end
|
|
56
76
|
|
|
57
77
|
# @param klass [Module]
|
|
@@ -88,9 +108,7 @@ module Iry
|
|
|
88
108
|
# result #=> nil
|
|
89
109
|
# fail_user.errors.details.fetch(:email) #=> [{error: :taken}]
|
|
90
110
|
def self.handle_constraints(model, &block)
|
|
91
|
-
handle_constraints
|
|
92
|
-
rescue StatementInvalid
|
|
93
|
-
return nil
|
|
111
|
+
TransformConstraints.handle_constraints(model, &block)
|
|
94
112
|
end
|
|
95
113
|
|
|
96
114
|
# Executes block and in case of constraints violations on `model`, block is
|
|
@@ -100,26 +118,7 @@ module Iry
|
|
|
100
118
|
# @yield block must perform the save operation, usually with `save`
|
|
101
119
|
# @return [Handlers::Model] returns `model` parameter
|
|
102
120
|
def self.handle_constraints!(model, &block)
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
block.()
|
|
106
|
-
|
|
107
|
-
return model
|
|
108
|
-
rescue ActiveRecord::StatementInvalid => err
|
|
109
|
-
handler = Handlers::Null
|
|
110
|
-
case
|
|
111
|
-
when Handlers::PG.handle?(err)
|
|
112
|
-
handler = Handlers::PG
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
is_handled = handler.handle(err, model)
|
|
116
|
-
|
|
117
|
-
# This constraint is not handled by Iry and should raise normally
|
|
118
|
-
if !is_handled
|
|
119
|
-
raise
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
raise StatementInvalid.new(err.message, sql: err.sql, binds: err.binds)
|
|
121
|
+
TransformConstraints.handle_constraints!(model, &block)
|
|
123
122
|
end
|
|
124
123
|
|
|
125
124
|
# Similar to {ActiveRecord::Base#save} but in case of constraint violations,
|
|
@@ -129,14 +128,7 @@ module Iry
|
|
|
129
128
|
# @param model [Handlers::Model] model to save
|
|
130
129
|
# @return [Boolean] `true` if successful
|
|
131
130
|
def self.save(model, ...)
|
|
132
|
-
|
|
133
|
-
constraint_model = handle_constraints(model) { success = model.save(...) }
|
|
134
|
-
|
|
135
|
-
if constraint_model
|
|
136
|
-
return success
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
return false
|
|
131
|
+
TransformConstraints.save(model, ...)
|
|
140
132
|
end
|
|
141
133
|
|
|
142
134
|
# Similar to {ActiveRecord::Base#save!} but in case of constraint violations,
|
|
@@ -151,13 +143,7 @@ module Iry
|
|
|
151
143
|
# @raise [ActiveRecord::RecordInvalid] triggered when a validation error is
|
|
152
144
|
# raised, but not a constraint violation
|
|
153
145
|
def self.save!(model, ...)
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
if constraint_model
|
|
157
|
-
return true
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
raise ConstraintViolation.new(model)
|
|
146
|
+
TransformConstraints.save!(model, ...)
|
|
161
147
|
end
|
|
162
148
|
|
|
163
149
|
# Similar to {ActiveRecord::Base#destroy} but in case of constraint
|
|
@@ -165,12 +151,6 @@ module Iry
|
|
|
165
151
|
# @param model [Handlers::Model] model to destroy
|
|
166
152
|
# @return [Handlers::Model] the destroyed model
|
|
167
153
|
def self.destroy(model)
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
if constraint_result.nil?
|
|
171
|
-
return false
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
return constraint_result
|
|
154
|
+
TransformConstraints.destroy(model)
|
|
175
155
|
end
|
|
176
156
|
end
|
data/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iry",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "iry",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.6.0",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"conventional-changelog-cli": ">= 3.0.0",
|
data/package.json
CHANGED
data/rbi/iry.rbi
CHANGED
|
@@ -101,13 +101,44 @@ module Iry
|
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
# Raised when constraints have been violated and have been converted to
|
|
104
|
-
# model errors
|
|
104
|
+
# model errors, on {ActiveRecord::Base#save!} calls, to simulate a behavior
|
|
105
|
+
# similar to {ActiveRecord::RecordInvalid} when it's raised
|
|
105
106
|
class ConstraintViolation < ActiveRecord::RecordInvalid
|
|
106
107
|
include Iry::Error
|
|
107
108
|
end
|
|
108
109
|
|
|
110
|
+
# Raised when constraints errors happen and go through Iry, even if these
|
|
111
|
+
# are not handled. This class inherits from {ActiveRecord::StatementInvalid}
|
|
112
|
+
# to maximize compatibility with existing code
|
|
109
113
|
class StatementInvalid < ActiveRecord::StatementInvalid
|
|
110
114
|
include Iry::Error
|
|
115
|
+
|
|
116
|
+
# sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
|
|
117
|
+
# sord omit - no YARD type given for "**kwargs", using untyped
|
|
118
|
+
# _@param_ `message`
|
|
119
|
+
#
|
|
120
|
+
# _@param_ `record`
|
|
121
|
+
#
|
|
122
|
+
# _@param_ `error`
|
|
123
|
+
sig do
|
|
124
|
+
params(
|
|
125
|
+
message: T.nilable(String),
|
|
126
|
+
record: Handlers::Model,
|
|
127
|
+
error: ActiveModel::Error,
|
|
128
|
+
kwargs: T.untyped
|
|
129
|
+
).void
|
|
130
|
+
end
|
|
131
|
+
def initialize(message = nil, record:, error:, **kwargs); end
|
|
132
|
+
|
|
133
|
+
# _@return_ — model affected by the constraint violation
|
|
134
|
+
sig { returns(Handlers::Model) }
|
|
135
|
+
attr_reader :record
|
|
136
|
+
|
|
137
|
+
# sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
|
|
138
|
+
# _@return_ — error attached to the `record` for the
|
|
139
|
+
# constraint violation
|
|
140
|
+
sig { returns(ActiveModel::Error) }
|
|
141
|
+
attr_reader :error
|
|
111
142
|
end
|
|
112
143
|
|
|
113
144
|
# Overrides private API method {ActiveRecord#create_or_update} to handle
|
|
@@ -201,8 +232,9 @@ module Iry
|
|
|
201
232
|
#
|
|
202
233
|
# _@param_ `model`
|
|
203
234
|
#
|
|
204
|
-
# _@return_ —
|
|
205
|
-
|
|
235
|
+
# _@return_ — `nil` if couldn't handle the error,
|
|
236
|
+
# otherwise the {ActiveModel::Error} added to the model
|
|
237
|
+
sig { params(err: ActiveRecord::StatementInvalid, model: Model).void }
|
|
206
238
|
def handle(err, model); end
|
|
207
239
|
end
|
|
208
240
|
|
|
@@ -257,6 +289,10 @@ module Iry
|
|
|
257
289
|
# _@param_ `err`
|
|
258
290
|
#
|
|
259
291
|
# _@param_ `model` — should inherit {ActiveRecord::Base} and`include Iry` to match the interface
|
|
292
|
+
#
|
|
293
|
+
# _@return_ — if handled constraint, returns the
|
|
294
|
+
# error attached to the model. If constraint wasn't handled or handling
|
|
295
|
+
# failed, `nil` is returned
|
|
260
296
|
sig { params(err: ActiveRecord::StatementInvalid, model: Model).void }
|
|
261
297
|
def handle(err, model); end
|
|
262
298
|
|
|
@@ -275,6 +311,10 @@ module Iry
|
|
|
275
311
|
# _@param_ `err`
|
|
276
312
|
#
|
|
277
313
|
# _@param_ `model` — should inherit {ActiveRecord::Base} and`include Iry` to match the interface
|
|
314
|
+
#
|
|
315
|
+
# _@return_ — if handled constraint, returns the
|
|
316
|
+
# error attached to the model. If constraint wasn't handled or handling
|
|
317
|
+
# failed, `nil` is returned
|
|
278
318
|
sig { params(err: ActiveRecord::StatementInvalid, model: Model).void }
|
|
279
319
|
def self.handle(err, model); end
|
|
280
320
|
end
|
|
@@ -297,7 +337,7 @@ module Iry
|
|
|
297
337
|
# _@param_ `err`
|
|
298
338
|
#
|
|
299
339
|
# _@param_ `model` — should inherit {ActiveRecord::Base} and`include Iry` to match the interface
|
|
300
|
-
sig { params(err: ActiveRecord::StatementInvalid, model: Model).
|
|
340
|
+
sig { params(err: ActiveRecord::StatementInvalid, model: Model).void }
|
|
301
341
|
def handle(err, model); end
|
|
302
342
|
|
|
303
343
|
# sord warn - ActiveRecord::StatementInvalid wasn't able to be resolved to a constant in this project
|
|
@@ -313,7 +353,7 @@ module Iry
|
|
|
313
353
|
# _@param_ `err`
|
|
314
354
|
#
|
|
315
355
|
# _@param_ `model` — should inherit {ActiveRecord::Base} and`include Iry` to match the interface
|
|
316
|
-
sig { params(err: ActiveRecord::StatementInvalid, model: Model).
|
|
356
|
+
sig { params(err: ActiveRecord::StatementInvalid, model: Model).void }
|
|
317
357
|
def self.handle(err, model); end
|
|
318
358
|
end
|
|
319
359
|
end
|
|
@@ -337,10 +377,11 @@ module Iry
|
|
|
337
377
|
# A constraint has a name and can apply errors to an object inheriting from {ActiveRecord::Base}
|
|
338
378
|
# @abstract
|
|
339
379
|
module Constraint
|
|
380
|
+
# sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
|
|
340
381
|
# Sets validation errors on the model
|
|
341
382
|
#
|
|
342
383
|
# _@param_ `model`
|
|
343
|
-
sig { params(model: Handlers::Model).
|
|
384
|
+
sig { params(model: Handlers::Model).returns(ActiveModel::Error) }
|
|
344
385
|
def apply(model); end
|
|
345
386
|
|
|
346
387
|
# Name of the constraint to be caught from the database
|
|
@@ -369,8 +410,9 @@ module Iry
|
|
|
369
410
|
sig { params(key: Symbol, name: String, message: T.any(Symbol, String)).void }
|
|
370
411
|
def initialize(key, name:, message: :invalid); end
|
|
371
412
|
|
|
413
|
+
# sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
|
|
372
414
|
# _@param_ `model`
|
|
373
|
-
sig { params(model: Handlers::Model).
|
|
415
|
+
sig { params(model: Handlers::Model).returns(ActiveModel::Error) }
|
|
374
416
|
def apply(model); end
|
|
375
417
|
|
|
376
418
|
sig { returns(Symbol) }
|
|
@@ -409,8 +451,9 @@ module Iry
|
|
|
409
451
|
end
|
|
410
452
|
def initialize(keys, name:, error_key:, message: :taken); end
|
|
411
453
|
|
|
454
|
+
# sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
|
|
412
455
|
# _@param_ `model`
|
|
413
|
-
sig { params(model: Handlers::Model).
|
|
456
|
+
sig { params(model: Handlers::Model).returns(ActiveModel::Error) }
|
|
414
457
|
def apply(model); end
|
|
415
458
|
|
|
416
459
|
sig { returns(T::Array[Symbol]) }
|
|
@@ -443,8 +486,9 @@ module Iry
|
|
|
443
486
|
sig { params(key: Symbol, name: String, message: T.any(Symbol, String)).void }
|
|
444
487
|
def initialize(key, name:, message: :taken); end
|
|
445
488
|
|
|
489
|
+
# sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
|
|
446
490
|
# _@param_ `model`
|
|
447
|
-
sig { params(model: Handlers::Model).
|
|
491
|
+
sig { params(model: Handlers::Model).returns(ActiveModel::Error) }
|
|
448
492
|
def apply(model); end
|
|
449
493
|
|
|
450
494
|
sig { returns(Symbol) }
|
|
@@ -483,8 +527,9 @@ module Iry
|
|
|
483
527
|
end
|
|
484
528
|
def initialize(keys, name:, error_key:, message: :required); end
|
|
485
529
|
|
|
530
|
+
# sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
|
|
486
531
|
# _@param_ `model`
|
|
487
|
-
sig { params(model: Handlers::Model).
|
|
532
|
+
sig { params(model: Handlers::Model).returns(ActiveModel::Error) }
|
|
488
533
|
def apply(model); end
|
|
489
534
|
|
|
490
535
|
sig { returns(T::Array[Symbol]) }
|
|
@@ -500,4 +545,66 @@ module Iry
|
|
|
500
545
|
attr_accessor :error_key
|
|
501
546
|
end
|
|
502
547
|
end
|
|
548
|
+
|
|
549
|
+
# Implementation of {Iry} methods, helps ensuring the main module focus on
|
|
550
|
+
# documentation
|
|
551
|
+
module TransformConstraints
|
|
552
|
+
extend Iry::TransformConstraints
|
|
553
|
+
|
|
554
|
+
# _@param_ `model`
|
|
555
|
+
sig { params(model: Handlers::Model, block: T.untyped).void }
|
|
556
|
+
def handle_constraints(model, &block); end
|
|
557
|
+
|
|
558
|
+
# _@param_ `model`
|
|
559
|
+
sig { params(model: Handlers::Model, block: T.untyped).returns(Handlers::Model) }
|
|
560
|
+
def handle_constraints!(model, &block); end
|
|
561
|
+
|
|
562
|
+
# Tracks constraints of models saved as a consequence of saving another
|
|
563
|
+
# model. This usually represents a situation of model using
|
|
564
|
+
# `accepts_nested_attributes_for`
|
|
565
|
+
#
|
|
566
|
+
# _@param_ `model`
|
|
567
|
+
sig { params(model: Handlers::Model, block: T.untyped).returns(Handlers::Model) }
|
|
568
|
+
def nested_constraints!(model, &block); end
|
|
569
|
+
|
|
570
|
+
# _@param_ `model`
|
|
571
|
+
sig { params(model: Handlers::Model).returns(T::Boolean) }
|
|
572
|
+
def save(model); end
|
|
573
|
+
|
|
574
|
+
# _@param_ `model`
|
|
575
|
+
sig { params(model: Handlers::Model).returns(T::Boolean) }
|
|
576
|
+
def save!(model); end
|
|
577
|
+
|
|
578
|
+
# _@param_ `model`
|
|
579
|
+
sig { params(model: Handlers::Model).returns(Handlers::Model) }
|
|
580
|
+
def destroy(model); end
|
|
581
|
+
|
|
582
|
+
# _@param_ `model`
|
|
583
|
+
sig { params(model: Handlers::Model, block: T.untyped).void }
|
|
584
|
+
def self.handle_constraints(model, &block); end
|
|
585
|
+
|
|
586
|
+
# _@param_ `model`
|
|
587
|
+
sig { params(model: Handlers::Model, block: T.untyped).returns(Handlers::Model) }
|
|
588
|
+
def self.handle_constraints!(model, &block); end
|
|
589
|
+
|
|
590
|
+
# Tracks constraints of models saved as a consequence of saving another
|
|
591
|
+
# model. This usually represents a situation of model using
|
|
592
|
+
# `accepts_nested_attributes_for`
|
|
593
|
+
#
|
|
594
|
+
# _@param_ `model`
|
|
595
|
+
sig { params(model: Handlers::Model, block: T.untyped).returns(Handlers::Model) }
|
|
596
|
+
def self.nested_constraints!(model, &block); end
|
|
597
|
+
|
|
598
|
+
# _@param_ `model`
|
|
599
|
+
sig { params(model: Handlers::Model).returns(T::Boolean) }
|
|
600
|
+
def self.save(model); end
|
|
601
|
+
|
|
602
|
+
# _@param_ `model`
|
|
603
|
+
sig { params(model: Handlers::Model).returns(T::Boolean) }
|
|
604
|
+
def self.save!(model); end
|
|
605
|
+
|
|
606
|
+
# _@param_ `model`
|
|
607
|
+
sig { params(model: Handlers::Model).returns(Handlers::Model) }
|
|
608
|
+
def self.destroy(model); end
|
|
609
|
+
end
|
|
503
610
|
end
|
data/sig/iry.rbs
CHANGED
|
@@ -93,13 +93,39 @@ module Iry
|
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
# Raised when constraints have been violated and have been converted to
|
|
96
|
-
# model errors
|
|
96
|
+
# model errors, on {ActiveRecord::Base#save!} calls, to simulate a behavior
|
|
97
|
+
# similar to {ActiveRecord::RecordInvalid} when it's raised
|
|
97
98
|
class ConstraintViolation < ActiveRecord::RecordInvalid
|
|
98
99
|
include Iry::Error
|
|
99
100
|
end
|
|
100
101
|
|
|
102
|
+
# Raised when constraints errors happen and go through Iry, even if these
|
|
103
|
+
# are not handled. This class inherits from {ActiveRecord::StatementInvalid}
|
|
104
|
+
# to maximize compatibility with existing code
|
|
101
105
|
class StatementInvalid < ActiveRecord::StatementInvalid
|
|
102
106
|
include Iry::Error
|
|
107
|
+
|
|
108
|
+
# sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
|
|
109
|
+
# sord omit - no YARD type given for "**kwargs", using untyped
|
|
110
|
+
# _@param_ `message`
|
|
111
|
+
#
|
|
112
|
+
# _@param_ `record`
|
|
113
|
+
#
|
|
114
|
+
# _@param_ `error`
|
|
115
|
+
def initialize: (
|
|
116
|
+
?String? message,
|
|
117
|
+
record: Handlers::Model,
|
|
118
|
+
error: ActiveModel::Error,
|
|
119
|
+
**untyped kwargs
|
|
120
|
+
) -> void
|
|
121
|
+
|
|
122
|
+
# _@return_ — model affected by the constraint violation
|
|
123
|
+
attr_reader record: Handlers::Model
|
|
124
|
+
|
|
125
|
+
# sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
|
|
126
|
+
# _@return_ — error attached to the `record` for the
|
|
127
|
+
# constraint violation
|
|
128
|
+
attr_reader error: ActiveModel::Error
|
|
103
129
|
end
|
|
104
130
|
|
|
105
131
|
# Overrides private API method {ActiveRecord#create_or_update} to handle
|
|
@@ -182,8 +208,9 @@ module Iry
|
|
|
182
208
|
#
|
|
183
209
|
# _@param_ `model`
|
|
184
210
|
#
|
|
185
|
-
# _@return_ —
|
|
186
|
-
|
|
211
|
+
# _@return_ — `nil` if couldn't handle the error,
|
|
212
|
+
# otherwise the {ActiveModel::Error} added to the model
|
|
213
|
+
def handle: (ActiveRecord::StatementInvalid err, Model model) -> void
|
|
187
214
|
end
|
|
188
215
|
|
|
189
216
|
# Interface of the model class. This class is usually inherits from {ActiveRecord::Base}
|
|
@@ -224,6 +251,10 @@ module Iry
|
|
|
224
251
|
# _@param_ `err`
|
|
225
252
|
#
|
|
226
253
|
# _@param_ `model` — should inherit {ActiveRecord::Base} and`include Iry` to match the interface
|
|
254
|
+
#
|
|
255
|
+
# _@return_ — if handled constraint, returns the
|
|
256
|
+
# error attached to the model. If constraint wasn't handled or handling
|
|
257
|
+
# failed, `nil` is returned
|
|
227
258
|
def handle: (ActiveRecord::StatementInvalid err, Model model) -> void
|
|
228
259
|
|
|
229
260
|
# sord warn - ActiveRecord::StatementInvalid wasn't able to be resolved to a constant in this project
|
|
@@ -240,6 +271,10 @@ module Iry
|
|
|
240
271
|
# _@param_ `err`
|
|
241
272
|
#
|
|
242
273
|
# _@param_ `model` — should inherit {ActiveRecord::Base} and`include Iry` to match the interface
|
|
274
|
+
#
|
|
275
|
+
# _@return_ — if handled constraint, returns the
|
|
276
|
+
# error attached to the model. If constraint wasn't handled or handling
|
|
277
|
+
# failed, `nil` is returned
|
|
243
278
|
def self.handle: (ActiveRecord::StatementInvalid err, Model model) -> void
|
|
244
279
|
end
|
|
245
280
|
|
|
@@ -260,7 +295,7 @@ module Iry
|
|
|
260
295
|
# _@param_ `err`
|
|
261
296
|
#
|
|
262
297
|
# _@param_ `model` — should inherit {ActiveRecord::Base} and`include Iry` to match the interface
|
|
263
|
-
def handle: (ActiveRecord::StatementInvalid err, Model model) ->
|
|
298
|
+
def handle: (ActiveRecord::StatementInvalid err, Model model) -> void
|
|
264
299
|
|
|
265
300
|
# sord warn - ActiveRecord::StatementInvalid wasn't able to be resolved to a constant in this project
|
|
266
301
|
# Returns always true, catching any unhandled database exception
|
|
@@ -274,7 +309,7 @@ module Iry
|
|
|
274
309
|
# _@param_ `err`
|
|
275
310
|
#
|
|
276
311
|
# _@param_ `model` — should inherit {ActiveRecord::Base} and`include Iry` to match the interface
|
|
277
|
-
def self.handle: (ActiveRecord::StatementInvalid err, Model model) ->
|
|
312
|
+
def self.handle: (ActiveRecord::StatementInvalid err, Model model) -> void
|
|
278
313
|
end
|
|
279
314
|
end
|
|
280
315
|
|
|
@@ -295,10 +330,11 @@ module Iry
|
|
|
295
330
|
# A constraint has a name and can apply errors to an object inheriting from {ActiveRecord::Base}
|
|
296
331
|
# @abstract
|
|
297
332
|
module Constraint
|
|
333
|
+
# sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
|
|
298
334
|
# Sets validation errors on the model
|
|
299
335
|
#
|
|
300
336
|
# _@param_ `model`
|
|
301
|
-
def apply: (Handlers::Model model) ->
|
|
337
|
+
def apply: (Handlers::Model model) -> ActiveModel::Error
|
|
302
338
|
|
|
303
339
|
# Name of the constraint to be caught from the database
|
|
304
340
|
def name: () -> String
|
|
@@ -322,8 +358,9 @@ module Iry
|
|
|
322
358
|
# _@param_ `name` — constraint name
|
|
323
359
|
def initialize: (Symbol key, name: String, ?message: (Symbol | String)) -> void
|
|
324
360
|
|
|
361
|
+
# sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
|
|
325
362
|
# _@param_ `model`
|
|
326
|
-
def apply: (Handlers::Model model) ->
|
|
363
|
+
def apply: (Handlers::Model model) -> ActiveModel::Error
|
|
327
364
|
|
|
328
365
|
attr_accessor key: Symbol
|
|
329
366
|
|
|
@@ -354,8 +391,9 @@ module Iry
|
|
|
354
391
|
?message: (Symbol | String)
|
|
355
392
|
) -> void
|
|
356
393
|
|
|
394
|
+
# sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
|
|
357
395
|
# _@param_ `model`
|
|
358
|
-
def apply: (Handlers::Model model) ->
|
|
396
|
+
def apply: (Handlers::Model model) -> ActiveModel::Error
|
|
359
397
|
|
|
360
398
|
attr_accessor keys: ::Array[Symbol]
|
|
361
399
|
|
|
@@ -381,8 +419,9 @@ module Iry
|
|
|
381
419
|
# _@param_ `name` — constraint name
|
|
382
420
|
def initialize: (Symbol key, name: String, ?message: (Symbol | String)) -> void
|
|
383
421
|
|
|
422
|
+
# sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
|
|
384
423
|
# _@param_ `model`
|
|
385
|
-
def apply: (Handlers::Model model) ->
|
|
424
|
+
def apply: (Handlers::Model model) -> ActiveModel::Error
|
|
386
425
|
|
|
387
426
|
attr_accessor key: Symbol
|
|
388
427
|
|
|
@@ -413,8 +452,9 @@ module Iry
|
|
|
413
452
|
?message: (Symbol | String)
|
|
414
453
|
) -> void
|
|
415
454
|
|
|
455
|
+
# sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
|
|
416
456
|
# _@param_ `model`
|
|
417
|
-
def apply: (Handlers::Model model) ->
|
|
457
|
+
def apply: (Handlers::Model model) -> ActiveModel::Error
|
|
418
458
|
|
|
419
459
|
attr_accessor keys: ::Array[Symbol]
|
|
420
460
|
|
|
@@ -425,4 +465,54 @@ module Iry
|
|
|
425
465
|
attr_accessor error_key: Symbol
|
|
426
466
|
end
|
|
427
467
|
end
|
|
468
|
+
|
|
469
|
+
# Implementation of {Iry} methods, helps ensuring the main module focus on
|
|
470
|
+
# documentation
|
|
471
|
+
module TransformConstraints
|
|
472
|
+
extend Iry::TransformConstraints
|
|
473
|
+
|
|
474
|
+
# _@param_ `model`
|
|
475
|
+
def handle_constraints: (Handlers::Model model) -> void
|
|
476
|
+
|
|
477
|
+
# _@param_ `model`
|
|
478
|
+
def handle_constraints!: (Handlers::Model model) -> Handlers::Model
|
|
479
|
+
|
|
480
|
+
# Tracks constraints of models saved as a consequence of saving another
|
|
481
|
+
# model. This usually represents a situation of model using
|
|
482
|
+
# `accepts_nested_attributes_for`
|
|
483
|
+
#
|
|
484
|
+
# _@param_ `model`
|
|
485
|
+
def nested_constraints!: (Handlers::Model model) -> Handlers::Model
|
|
486
|
+
|
|
487
|
+
# _@param_ `model`
|
|
488
|
+
def save: (Handlers::Model model) -> bool
|
|
489
|
+
|
|
490
|
+
# _@param_ `model`
|
|
491
|
+
def save!: (Handlers::Model model) -> bool
|
|
492
|
+
|
|
493
|
+
# _@param_ `model`
|
|
494
|
+
def destroy: (Handlers::Model model) -> Handlers::Model
|
|
495
|
+
|
|
496
|
+
# _@param_ `model`
|
|
497
|
+
def self.handle_constraints: (Handlers::Model model) -> void
|
|
498
|
+
|
|
499
|
+
# _@param_ `model`
|
|
500
|
+
def self.handle_constraints!: (Handlers::Model model) -> Handlers::Model
|
|
501
|
+
|
|
502
|
+
# Tracks constraints of models saved as a consequence of saving another
|
|
503
|
+
# model. This usually represents a situation of model using
|
|
504
|
+
# `accepts_nested_attributes_for`
|
|
505
|
+
#
|
|
506
|
+
# _@param_ `model`
|
|
507
|
+
def self.nested_constraints!: (Handlers::Model model) -> Handlers::Model
|
|
508
|
+
|
|
509
|
+
# _@param_ `model`
|
|
510
|
+
def self.save: (Handlers::Model model) -> bool
|
|
511
|
+
|
|
512
|
+
# _@param_ `model`
|
|
513
|
+
def self.save!: (Handlers::Model model) -> bool
|
|
514
|
+
|
|
515
|
+
# _@param_ `model`
|
|
516
|
+
def self.destroy: (Handlers::Model model) -> Handlers::Model
|
|
517
|
+
end
|
|
428
518
|
end
|
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.6.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-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -107,6 +107,7 @@ files:
|
|
|
107
107
|
- lib/iry/handlers/pg.rb
|
|
108
108
|
- lib/iry/macros.rb
|
|
109
109
|
- lib/iry/patch.rb
|
|
110
|
+
- lib/iry/transform_constraints.rb
|
|
110
111
|
- lib/iry/version.rb
|
|
111
112
|
- package-lock.json
|
|
112
113
|
- package.json
|