active_record_compose 0.1.8 → 0.2.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 +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +10 -0
- data/README.md +24 -0
- data/lib/active_record_compose/delegate_attribute.rb +5 -1
- data/lib/active_record_compose/inner_model.rb +2 -1
- data/lib/active_record_compose/model.rb +10 -2
- data/lib/active_record_compose/version.rb +1 -1
- data/sig/active_record_compose.rbs +100 -0
- metadata +5 -5
- data/Rakefile +0 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0c3cb23854b3caafb1f25c297b1d12fb7693c5af5d8e7f917ce3117e5334afa0
|
|
4
|
+
data.tar.gz: fe905d6071cc4c491fadd68c35b36540b57881d78b6c398acaf2e573d766912c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6a8850ebb01e4705f658bbc65c2cc10366214a2c34787b3d6c6228c34ac405aa00b548212747ef5429fe26eabe1633bf5af9d1019bd95094c1cfd79897811d4c
|
|
7
|
+
data.tar.gz: a531f7980d9d5ed490aa8c35927176511db6ff81f81009d02ac4121a04abe57efd6ac4dc5db8f353b4ef03c18214c73f246a1c6c8e43e235d1065d436538de31
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.2.1] - 2024-01-31
|
|
4
|
+
|
|
5
|
+
- in `#save` (without bang), `ActiveRecord::RecordInvalid` error is not passed outward.
|
|
6
|
+
|
|
7
|
+
## [0.2.0] - 2024-01-21
|
|
8
|
+
|
|
9
|
+
- add i18n doc.
|
|
10
|
+
- add sig/
|
|
11
|
+
- add typecheck for ci.
|
|
12
|
+
|
|
3
13
|
## [0.1.8] - 2024-01-16
|
|
4
14
|
|
|
5
15
|
- avoid executing `#save!` from `Model#save`
|
data/README.md
CHANGED
|
@@ -271,6 +271,30 @@ model.update
|
|
|
271
271
|
# after_save called!
|
|
272
272
|
```
|
|
273
273
|
|
|
274
|
+
### I18n
|
|
275
|
+
|
|
276
|
+
When the `#save!` operation raises an `ActiveRecord::RecordInvalid` exception, it is necessary to have pre-existing locale definitions in order to construct i18n information correctly.
|
|
277
|
+
The specific keys required are `activemodel.errors.messages.record_invalid` or `errors.messages.record_invalid`.
|
|
278
|
+
|
|
279
|
+
(Replace `en` as appropriate in the context.)
|
|
280
|
+
|
|
281
|
+
```yaml
|
|
282
|
+
en:
|
|
283
|
+
activemodel:
|
|
284
|
+
errors:
|
|
285
|
+
messages:
|
|
286
|
+
record_invalid: 'Validation failed: %{errors}'
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Alternatively, the following definition is also acceptable:
|
|
290
|
+
|
|
291
|
+
```yaml
|
|
292
|
+
en:
|
|
293
|
+
errors:
|
|
294
|
+
messages:
|
|
295
|
+
record_invalid: 'Validation failed: %{errors}'
|
|
296
|
+
```
|
|
297
|
+
|
|
274
298
|
## Development
|
|
275
299
|
|
|
276
300
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
@@ -63,7 +63,11 @@ module ActiveRecordCompose
|
|
|
63
63
|
#
|
|
64
64
|
# @return [Hash] hash with the attribute name as key and the attribute value as value.
|
|
65
65
|
def attributes
|
|
66
|
-
|
|
66
|
+
# steep:ignore all
|
|
67
|
+
attrs = defined?(super) ? super : {}
|
|
68
|
+
# steep:ignore end
|
|
69
|
+
# @type var attrs: Hash[String, untyped]
|
|
70
|
+
attrs.merge(delegated_attributes.to_h { [_1, public_send(_1)] })
|
|
67
71
|
end
|
|
68
72
|
end
|
|
69
73
|
end
|
|
@@ -16,7 +16,8 @@ module ActiveRecordCompose
|
|
|
16
16
|
|
|
17
17
|
# @return [Symbol] :save or :destroy
|
|
18
18
|
def context
|
|
19
|
-
|
|
19
|
+
c = @context
|
|
20
|
+
ret = c.is_a?(Proc) ? c.call(model) : c
|
|
20
21
|
ret.presence_in(%i[save destroy]) || :save
|
|
21
22
|
end
|
|
22
23
|
|
|
@@ -19,7 +19,9 @@ module ActiveRecordCompose
|
|
|
19
19
|
validate :validate_models
|
|
20
20
|
|
|
21
21
|
def initialize(attributes = {})
|
|
22
|
+
# steep:ignore all
|
|
22
23
|
super(attributes)
|
|
24
|
+
# steep:ignore end
|
|
23
25
|
end
|
|
24
26
|
|
|
25
27
|
# Save the models that exist in models.
|
|
@@ -32,6 +34,8 @@ module ActiveRecordCompose
|
|
|
32
34
|
return false if invalid?
|
|
33
35
|
|
|
34
36
|
save_in_transaction { save_models(bang: false) }
|
|
37
|
+
rescue ActiveRecord::RecordInvalid
|
|
38
|
+
false
|
|
35
39
|
end
|
|
36
40
|
|
|
37
41
|
# Save the models that exist in models.
|
|
@@ -75,6 +79,8 @@ module ActiveRecordCompose
|
|
|
75
79
|
return false if invalid?
|
|
76
80
|
|
|
77
81
|
save_in_transaction { run_callbacks(:create) { save_models(bang: false) } }
|
|
82
|
+
rescue ActiveRecord::RecordInvalid
|
|
83
|
+
false
|
|
78
84
|
end
|
|
79
85
|
|
|
80
86
|
# Behavior is same to `#create`, but raises an exception prematurely on failure.
|
|
@@ -116,6 +122,8 @@ module ActiveRecordCompose
|
|
|
116
122
|
return false if invalid?
|
|
117
123
|
|
|
118
124
|
save_in_transaction { run_callbacks(:update) { save_models(bang: false) } }
|
|
125
|
+
rescue ActiveRecord::RecordInvalid
|
|
126
|
+
false
|
|
119
127
|
end
|
|
120
128
|
|
|
121
129
|
# Behavior is same to `#update`, but raises an exception prematurely on failure.
|
|
@@ -135,10 +143,10 @@ module ActiveRecordCompose
|
|
|
135
143
|
|
|
136
144
|
def validate_models = wrapped_models.select { _1.invalid? }.each { errors.merge!(_1) }
|
|
137
145
|
|
|
138
|
-
def save_in_transaction(
|
|
146
|
+
def save_in_transaction(&block)
|
|
139
147
|
run_callbacks(:commit) do
|
|
140
148
|
result = ::ActiveRecord::Base.transaction do
|
|
141
|
-
raise ActiveRecord::Rollback unless run_callbacks(:save,
|
|
149
|
+
raise ActiveRecord::Rollback unless run_callbacks(:save, &block)
|
|
142
150
|
|
|
143
151
|
true
|
|
144
152
|
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# TypeProf 0.21.9
|
|
2
|
+
|
|
3
|
+
# Classes
|
|
4
|
+
module ActiveRecordCompose
|
|
5
|
+
VERSION: String
|
|
6
|
+
|
|
7
|
+
interface _ARLike
|
|
8
|
+
def is_a?: (untyped) -> bool
|
|
9
|
+
def save: -> bool
|
|
10
|
+
def save!: -> untyped
|
|
11
|
+
def destroy: -> bool
|
|
12
|
+
def destroy!: -> untyped
|
|
13
|
+
def invalid?: -> bool
|
|
14
|
+
def valid?: -> bool
|
|
15
|
+
def errors: -> untyped
|
|
16
|
+
def ==: (untyped) -> bool
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
type attribute_name = (String | Symbol)
|
|
20
|
+
type context_types = (:save | :destroy)
|
|
21
|
+
type context_proc = ^(_ARLike) -> context_types
|
|
22
|
+
type context = context_types | context_proc
|
|
23
|
+
|
|
24
|
+
module DelegateAttribute
|
|
25
|
+
extend ActiveSupport::Concern
|
|
26
|
+
|
|
27
|
+
def delegated_attribute: -> Array[untyped]
|
|
28
|
+
def attributes: -> Hash[String, untyped]
|
|
29
|
+
def delegated_attributes: -> Array[untyped]
|
|
30
|
+
def delegated_attributes=: (Array[untyped]) -> void
|
|
31
|
+
|
|
32
|
+
def self.class_attribute: (untyped, ?untyped) -> untyped
|
|
33
|
+
def delegate: (*untyped) -> untyped
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
class InnerModelCollection
|
|
37
|
+
include ::Enumerable[_ARLike]
|
|
38
|
+
@models: Array[InnerModel]
|
|
39
|
+
|
|
40
|
+
def each: () { (_ARLike) -> void } -> InnerModelCollection | () -> Enumerator[_ARLike, self]
|
|
41
|
+
def <<: (_ARLike) -> self
|
|
42
|
+
def push: (_ARLike, ?context: context) -> self
|
|
43
|
+
def empty?: -> bool
|
|
44
|
+
def clear: -> self
|
|
45
|
+
def delete: (_ARLike | InnerModel, ?context: context_types) -> InnerModelCollection?
|
|
46
|
+
def __each_by_wrapped: () { (InnerModel) -> void } -> InnerModelCollection | () -> Enumerator[InnerModel, self]
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
def models: -> Array[InnerModel]
|
|
50
|
+
def wrap: (_ARLike | InnerModel, context: context) -> InnerModel
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
class InnerModel
|
|
54
|
+
@context: context
|
|
55
|
+
|
|
56
|
+
def initialize: (_ARLike, ?context: context) -> void
|
|
57
|
+
def context: -> context
|
|
58
|
+
def save: -> bool
|
|
59
|
+
def save!: -> untyped
|
|
60
|
+
def invalid?: -> bool
|
|
61
|
+
def valid?: -> bool
|
|
62
|
+
def ==: (untyped) -> bool
|
|
63
|
+
def __raw_model: -> _ARLike
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
attr_reader model: _ARLike
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
class Model
|
|
70
|
+
extend ActiveModel::Callbacks
|
|
71
|
+
include ActiveModel::Model
|
|
72
|
+
include ActiveModel::Validations::Callbacks
|
|
73
|
+
include ActiveModel::Attributes
|
|
74
|
+
include ActiveRecord::Transactions
|
|
75
|
+
include DelegateAttribute
|
|
76
|
+
|
|
77
|
+
@__models: InnerModelCollection
|
|
78
|
+
|
|
79
|
+
def initialize: (?Hash[attribute_name, untyped]) -> void
|
|
80
|
+
def save: -> bool
|
|
81
|
+
def save!: -> untyped
|
|
82
|
+
def create: (?Hash[attribute_name, untyped]) -> bool
|
|
83
|
+
def create!: (?Hash[attribute_name, untyped]) -> untyped
|
|
84
|
+
def update: (?Hash[attribute_name, untyped]) -> bool
|
|
85
|
+
def update!: (?Hash[attribute_name, untyped]) -> untyped
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
def models: -> InnerModelCollection
|
|
89
|
+
def wrapped_models: -> Enumerator[InnerModel, InnerModelCollection]
|
|
90
|
+
def validate_models: -> void
|
|
91
|
+
def save_in_transaction: { -> bool } -> untyped
|
|
92
|
+
def save_models: (bang: bool) -> bool
|
|
93
|
+
def raise_validation_error: -> bot
|
|
94
|
+
def raise_on_save_error: -> bot
|
|
95
|
+
def raise_on_save_error_message: -> String
|
|
96
|
+
|
|
97
|
+
def self.validate: (*untyped) -> untyped
|
|
98
|
+
def run_callbacks: (untyped kind) ?{ () -> untyped } -> untyped
|
|
99
|
+
end
|
|
100
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active_record_compose
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- hamajyotan
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-01-
|
|
11
|
+
date: 2024-01-31 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -37,13 +37,13 @@ files:
|
|
|
37
37
|
- CODE_OF_CONDUCT.md
|
|
38
38
|
- LICENSE.txt
|
|
39
39
|
- README.md
|
|
40
|
-
- Rakefile
|
|
41
40
|
- lib/active_record_compose.rb
|
|
42
41
|
- lib/active_record_compose/delegate_attribute.rb
|
|
43
42
|
- lib/active_record_compose/inner_model.rb
|
|
44
43
|
- lib/active_record_compose/inner_model_collection.rb
|
|
45
44
|
- lib/active_record_compose/model.rb
|
|
46
45
|
- lib/active_record_compose/version.rb
|
|
46
|
+
- sig/active_record_compose.rbs
|
|
47
47
|
homepage: https://github.com/hamajyotan/active_record_compose
|
|
48
48
|
licenses:
|
|
49
49
|
- MIT
|
|
@@ -51,7 +51,7 @@ metadata:
|
|
|
51
51
|
homepage_uri: https://github.com/hamajyotan/active_record_compose
|
|
52
52
|
source_code_uri: https://github.com/hamajyotan/active_record_compose
|
|
53
53
|
changelog_uri: https://github.com/hamajyotan/active_record_compose/blob/main/CHANGELOG.md
|
|
54
|
-
documentation_uri: https://www.rubydoc.info/gems/active_record_compose/0.1
|
|
54
|
+
documentation_uri: https://www.rubydoc.info/gems/active_record_compose/0.2.1
|
|
55
55
|
rubygems_mfa_required: 'true'
|
|
56
56
|
post_install_message:
|
|
57
57
|
rdoc_options: []
|
|
@@ -68,7 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
68
68
|
- !ruby/object:Gem::Version
|
|
69
69
|
version: '0'
|
|
70
70
|
requirements: []
|
|
71
|
-
rubygems_version: 3.
|
|
71
|
+
rubygems_version: 3.5.5
|
|
72
72
|
signing_key:
|
|
73
73
|
specification_version: 4
|
|
74
74
|
summary: activemodel form object pattern
|