operations 0.7.1 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +12 -8
- data/UPGRADING_FORMS.md +1 -1
- data/lib/operations/command.rb +5 -0
- data/lib/operations/form/attribute.rb +16 -20
- data/lib/operations/form/base.rb +12 -5
- data/lib/operations/form.rb +21 -4
- data/lib/operations/version.rb +1 -1
- 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: affb68a66ecbc1ee0e687ab13efb202037d10054adb114e684e775224957b65e
|
4
|
+
data.tar.gz: 255180d0be3704a73c0bf6e148658df8b662e33a4508dff3ae3fee819e73caba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9f639386ccb6d003909737a4606b44f21cf49dc90b36fe0c854ea1e8c824049b2de7a70c480b44b2f4713558f21417c755361b6fccad4ed2f2af1068bc7cd135
|
7
|
+
data.tar.gz: a24d378627511c1198728a9aebe38c7f39cb057756e957906df29bf059804eef94d1188146b845842be42d94c559ebccd84b3d4d6a613b95a2a31d427771fe09
|
data/.rubocop_todo.yml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on 2024-
|
3
|
+
# on 2024-08-07 02:24:58 UTC using RuboCop version 1.65.0.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
@@ -22,14 +22,14 @@ Metrics/AbcSize:
|
|
22
22
|
# Offense count: 1
|
23
23
|
# Configuration parameters: CountComments, CountAsOne.
|
24
24
|
Metrics/ClassLength:
|
25
|
-
Max:
|
25
|
+
Max: 149
|
26
26
|
|
27
27
|
# Offense count: 1
|
28
28
|
# Configuration parameters: CountComments, CountAsOne.
|
29
29
|
Metrics/ModuleLength:
|
30
|
-
Max:
|
30
|
+
Max: 141
|
31
31
|
|
32
|
-
# Offense count:
|
32
|
+
# Offense count: 3
|
33
33
|
# Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
|
34
34
|
Metrics/ParameterLists:
|
35
35
|
Max: 7
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [0.7.2](https://github.com/BookingSync/operations/tree/v0.7.2)
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- Allow referencing and arbitrary model attrbiute from form object attribute with `model_name: "Post#title"` [\#50](https://github.com/BookingSync/operations/pull/50) ([pyromaniac](https://github.com/pyromaniac))
|
8
|
+
- Allow passing multiple `hydrators:` to Operations::Form [\#49](https://github.com/BookingSync/operations/pull/49) ([pyromaniac](https://github.com/pyromaniac))
|
9
|
+
|
10
|
+
### Improvements
|
11
|
+
|
12
|
+
- Change default form hydration behavior - it is now deep merging params after hydration, so no need to do it in the hydrator. Controlled with `hydration_merge_params:` option. [\#49](https://github.com/BookingSync/operations/pull/49) ([pyromaniac](https://github.com/pyromaniac))
|
13
|
+
|
3
14
|
## [0.7.1](https://github.com/BookingSync/operations/tree/v0.7.1)
|
4
15
|
|
5
16
|
### Added
|
data/README.md
CHANGED
@@ -312,7 +312,7 @@ class ActiveRecordRepository
|
|
312
312
|
include Dry::Monads[:result]
|
313
313
|
extend Dry::Initializer
|
314
314
|
|
315
|
-
param :model, type: Types
|
315
|
+
param :model, type: Types::Class.constrained(lt: ActiveRecord::Base)
|
316
316
|
|
317
317
|
def create(**attributes)
|
318
318
|
record = model.new(**attributes)
|
@@ -904,7 +904,7 @@ class Post::Update
|
|
904
904
|
def self.default_form
|
905
905
|
@default_form ||= Operations::Form.new(
|
906
906
|
default,
|
907
|
-
|
907
|
+
hydrators: [Post::Update::Hydrator.new]
|
908
908
|
)
|
909
909
|
end
|
910
910
|
end
|
@@ -912,9 +912,7 @@ end
|
|
912
912
|
class Post::Update::Hydrator
|
913
913
|
def call(form_class, params, post:, **_context)
|
914
914
|
value_attributes = form_class.attributes.keys - %i[post_id]
|
915
|
-
|
916
|
-
|
917
|
-
data.merge!(params)
|
915
|
+
value_attributes.index_with { |name| post.public_send(name) }
|
918
916
|
end
|
919
917
|
end
|
920
918
|
```
|
@@ -929,14 +927,20 @@ class Post::Update
|
|
929
927
|
@default_form ||= Operations::Form.new(
|
930
928
|
default,
|
931
929
|
model_map: Post::Update::ModelMap.new,
|
932
|
-
|
930
|
+
hydrators: [Post::Update::Hydrator.new]
|
933
931
|
)
|
934
932
|
end
|
935
933
|
end
|
936
934
|
|
937
935
|
class Post::Update::ModelMap
|
938
|
-
|
939
|
-
Post
|
936
|
+
MAPPING = {
|
937
|
+
%w[published_at] => Post, # a model can be passed but beware of circular dependencies, better use strings
|
938
|
+
%w[title] => "Post", # or a model name - safer option
|
939
|
+
%w[content] => "Post#body" # referencing different attribute is possible, useful for naming migration or translations
|
940
|
+
}.freeze
|
941
|
+
|
942
|
+
def call(path)
|
943
|
+
MAPPING[path] # returns the mapping for a single path
|
940
944
|
end
|
941
945
|
end
|
942
946
|
```
|
data/UPGRADING_FORMS.md
CHANGED
@@ -31,7 +31,7 @@ class Post::Update
|
|
31
31
|
def self.default_form
|
32
32
|
@default_form ||= Operations::Form.new(
|
33
33
|
default,
|
34
|
-
|
34
|
+
hydrators: [Post::Update::Hydrator.new],
|
35
35
|
model_map: Post::Update::ModelMap.new,
|
36
36
|
params_transformations: [
|
37
37
|
ParamsMap.new(id: :post_id)
|
data/lib/operations/command.rb
CHANGED
@@ -197,6 +197,11 @@ class Operations::Command
|
|
197
197
|
result_policies = policies_sum - [Undefined] unless policies_sum == [Undefined, Undefined]
|
198
198
|
options[:policies] = result_policies if result_policies
|
199
199
|
|
200
|
+
if after.present?
|
201
|
+
ActiveSupport::Deprecation.new.warn("Operations::Command `after:` option is deprecated and will be " \
|
202
|
+
"removed in 1.0.0. Please use `on_success:` instead")
|
203
|
+
end
|
204
|
+
|
200
205
|
preconditions.push(precondition) if precondition.present?
|
201
206
|
super(operation, preconditions: preconditions, on_success: after, **options)
|
202
207
|
end
|
@@ -5,39 +5,35 @@
|
|
5
5
|
# legacy UI.
|
6
6
|
class Operations::Form::Attribute
|
7
7
|
extend Dry::Initializer
|
8
|
-
include Dry::Equalizer(:name, :collection, :
|
9
|
-
include Operations::Inspect.new(:name, :collection, :
|
8
|
+
include Dry::Equalizer(:name, :collection, :model_class, :model_attribute, :form)
|
9
|
+
include Operations::Inspect.new(:name, :collection, :model_class, :model_attribute, :form)
|
10
10
|
|
11
11
|
param :name, type: Operations::Types::Coercible::Symbol
|
12
12
|
option :collection, type: Operations::Types::Bool, default: proc { false }
|
13
|
-
option :model_name,
|
14
|
-
type: (Operations::Types::String | Operations::Types.Instance(Class).constrained(lt: ActiveRecord::Base)).optional,
|
15
|
-
default: proc {}
|
13
|
+
option :model_name, type: (Operations::Types::String | Operations::Types::Class).optional, default: proc {}
|
16
14
|
option :form, type: Operations::Types::Class.optional, default: proc {}
|
17
15
|
|
18
|
-
def
|
19
|
-
@
|
20
|
-
end
|
16
|
+
def model_class
|
17
|
+
return @model_class if defined?(@model_class)
|
21
18
|
|
22
|
-
|
23
|
-
owning_model.human_attribute_name(string_name, options) if model_name
|
19
|
+
@model_class = model_name.is_a?(String) ? model_name.split("#").first.constantize : model_name
|
24
20
|
end
|
25
21
|
|
26
|
-
def
|
27
|
-
@
|
28
|
-
end
|
22
|
+
def model_attribute
|
23
|
+
return @model_attribute if defined?(@model_attribute)
|
29
24
|
|
30
|
-
|
31
|
-
owning_model.localized_attr_name_for(string_name, locale) if model_name
|
25
|
+
@model_attribute = model_class && (model_name.to_s.split("#").second.presence || name.to_s)
|
32
26
|
end
|
33
27
|
|
34
|
-
|
28
|
+
def model_type
|
29
|
+
model_class.type_for_attribute(model_attribute) if model_name
|
30
|
+
end
|
35
31
|
|
36
|
-
def
|
37
|
-
|
32
|
+
def model_human_name(options = {})
|
33
|
+
model_class.human_attribute_name(model_attribute, options) if model_name
|
38
34
|
end
|
39
35
|
|
40
|
-
def
|
41
|
-
|
36
|
+
def model_validators
|
37
|
+
model_name ? model_class.validators_on(model_attribute) : []
|
42
38
|
end
|
43
39
|
end
|
data/lib/operations/form/base.rb
CHANGED
@@ -50,7 +50,13 @@ class Operations::Form::Base
|
|
50
50
|
base.class_attribute :persisted, instance_accessor: false, default: nil
|
51
51
|
|
52
52
|
base.define_method :initialize do |*args, **kwargs|
|
53
|
-
args.empty?
|
53
|
+
if args.empty?
|
54
|
+
# Initializing Operations::Form::Base instance
|
55
|
+
super(kwargs, **{})
|
56
|
+
else
|
57
|
+
# Initializing Operations::Form instance as form object (deprecated)
|
58
|
+
super(*args, **kwargs)
|
59
|
+
end
|
54
60
|
end
|
55
61
|
end
|
56
62
|
|
@@ -83,12 +89,13 @@ class Operations::Form::Base
|
|
83
89
|
|
84
90
|
# :nodoc:
|
85
91
|
module InstanceMethods
|
86
|
-
|
87
|
-
|
92
|
+
# Copied from globalize-accessors, should be deprecated and removed as it is not a core method
|
93
|
+
def localized_attr_name_for(attr_name, locale)
|
94
|
+
"#{attr_name}_#{locale.to_s.underscore}"
|
88
95
|
end
|
89
96
|
|
90
|
-
def
|
91
|
-
self.class.attributes[name.to_sym].
|
97
|
+
def type_for_attribute(name)
|
98
|
+
self.class.attributes[name.to_sym].model_type
|
92
99
|
end
|
93
100
|
|
94
101
|
def has_attribute?(name) # rubocop:disable Naming/PredicateName
|
data/lib/operations/form.rb
CHANGED
@@ -21,8 +21,10 @@
|
|
21
21
|
#
|
22
22
|
class Operations::Form
|
23
23
|
include Dry::Core::Constants
|
24
|
-
include Dry::Equalizer(:command, :model_map, :persisted,
|
25
|
-
|
24
|
+
include Dry::Equalizer(:command, :model_map, :persisted,
|
25
|
+
:params_transformations, :hydrators, :hydration_merge_params, :form_class)
|
26
|
+
include Operations::Inspect.new(:model_name, :model_map, :persisted,
|
27
|
+
:params_transformations, :hydrators, :hydration_merge_params, :form_class)
|
26
28
|
|
27
29
|
# We need to make deprecated inheritance from Operations::Form act exactly the
|
28
30
|
# same way as from Operations::Form::Base. In order to do this, we are encapsulating all the
|
@@ -51,10 +53,17 @@ class Operations::Form
|
|
51
53
|
option :persisted, type: Operations::Types::Bool, default: proc { true }
|
52
54
|
option :params_transformations, type: Operations::Types::Coercible::Array.of(Operations::Types.Interface(:call)),
|
53
55
|
default: proc { [] }
|
54
|
-
option :
|
56
|
+
option :hydrators, type: Operations::Types::Array.of(Operations::Types.Interface(:call)), default: proc { [] }
|
57
|
+
option :hydration_merge_params, type: Operations::Types::Bool, default: proc { true }
|
55
58
|
option :base_class, type: Operations::Types::Class, default: proc { ::Operations::Form::Base }
|
56
59
|
end)
|
57
60
|
|
61
|
+
def initialize(command, hydrator: nil, hydrators: [], **options)
|
62
|
+
hydrators.push(hydrator) if hydrator.present?
|
63
|
+
|
64
|
+
super(command, hydrators: hydrators, **options)
|
65
|
+
end
|
66
|
+
|
58
67
|
def build(params = EMPTY_HASH, **context)
|
59
68
|
instantiate_form(command.callable(transform_params(params, **context), **context))
|
60
69
|
end
|
@@ -81,12 +90,20 @@ class Operations::Form
|
|
81
90
|
|
82
91
|
def instantiate_form(operation_result)
|
83
92
|
form_class.new(
|
84
|
-
|
93
|
+
hydrate_params(form_class, operation_result.params, **operation_result.context),
|
85
94
|
messages: operation_result.errors.to_h,
|
86
95
|
operation_result: operation_result
|
87
96
|
)
|
88
97
|
end
|
89
98
|
|
99
|
+
def hydrate_params(form_class, params, **context)
|
100
|
+
hydrated_params = hydrators.inject({}) do |value, hydrator|
|
101
|
+
value.merge(hydrator.call(form_class, params, **context).deep_symbolize_keys)
|
102
|
+
end
|
103
|
+
hydrated_params.deep_merge!(params) if hydration_merge_params
|
104
|
+
hydrated_params
|
105
|
+
end
|
106
|
+
|
90
107
|
def key_map
|
91
108
|
@key_map ||= command.contract.schema.key_map
|
92
109
|
end
|
data/lib/operations/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: operations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arkadiy Zabazhanov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-08-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: appraisal
|