business_flow 0.10.0 → 0.11.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/Gemfile.lock +1 -1
- data/lib/business_flow/cacheable.rb +21 -15
- data/lib/business_flow/dsl.rb +52 -10
- data/lib/business_flow/step.rb +5 -6
- data/lib/business_flow/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74bfeb7c6a69ab685707ad54578b1d7defcf9965
|
4
|
+
data.tar.gz: c7cbebb026219e58f9adcb4ae2ad29de2c813201
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 816b7e6b843375488b16a19559fdfd64806d0283042a7577a919061f9625a4ddc577a029ff27454ecdf2febb7da04891c8a56fec48dc51c0496fc1e513fcd6f3
|
7
|
+
data.tar.gz: cff7f66cab24eca4215ce189bec3c92883c260b0edb84a43a76a3cb22002e5eaa75ef45bd96c39200d31c33bb2c7350916f2a6e4b0d92d3a1da9ca6177677fd7
|
data/Gemfile.lock
CHANGED
@@ -58,31 +58,37 @@ module BusinessFlow
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
# :reek:TooManyStatements This can't be easily simplified any further,
|
62
|
-
# as best as I can tell.
|
63
61
|
def execute(flow)
|
64
|
-
|
65
|
-
|
66
|
-
cache_options.to_store_options(flow)) do
|
67
|
-
result = add_cache_key(super(flow), flow)
|
68
|
-
raise FlowFailedException, result if result.errors?
|
69
|
-
result
|
62
|
+
with_cache(flow) do
|
63
|
+
super(flow)._business_flow_cacheable_finalize(flow.cache_key)
|
70
64
|
end
|
71
65
|
rescue FlowFailedException => exc
|
72
66
|
exc.flow
|
73
67
|
end
|
74
68
|
|
69
|
+
def with_cache(flow, &blk)
|
70
|
+
add_cache_key_to_result_class
|
71
|
+
catch(:halt_step) do
|
72
|
+
return cache_store.fetch(flow.cache_key,
|
73
|
+
cache_options.to_store_options(flow), &blk)
|
74
|
+
end
|
75
|
+
raise FlowFailedException, flow
|
76
|
+
end
|
77
|
+
|
78
|
+
RESULT_FINALIZE = proc do |cache_key|
|
79
|
+
@cache_key = cache_key
|
80
|
+
raise FlowFailedException, self if errors?
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
75
84
|
def add_cache_key_to_result_class
|
76
85
|
return if @cache_key_added
|
77
|
-
|
86
|
+
result_class = const_get(:Result)
|
87
|
+
DSL::PublicField.new(:cache_key).add_to(result_class)
|
88
|
+
result_class.send(:define_method, :_business_flow_cacheable_finalize,
|
89
|
+
RESULT_FINALIZE)
|
78
90
|
@cache_key_added = true
|
79
91
|
end
|
80
|
-
|
81
|
-
# :reek:UtilityFunction Not entirey sure where else to put this.
|
82
|
-
def add_cache_key(result, flow)
|
83
|
-
result.instance_variable_set('@cache_key'.freeze, flow.cache_key)
|
84
|
-
result
|
85
|
-
end
|
86
92
|
end
|
87
93
|
end
|
88
94
|
end
|
data/lib/business_flow/dsl.rb
CHANGED
@@ -25,6 +25,9 @@ module BusinessFlow
|
|
25
25
|
# Declares that you will expose a field to the outside world.
|
26
26
|
def provides(*fields)
|
27
27
|
@provides ||= FieldList.new([], PublicField, [self, const_get(:Result)])
|
28
|
+
@result_copy ||= 'def from_flow(flow)'
|
29
|
+
@result_copy += fields.map { |field| "@#{field} = flow.#{field}" }
|
30
|
+
.join("\n")
|
28
31
|
@provides.add_fields(fields)
|
29
32
|
end
|
30
33
|
|
@@ -55,10 +58,11 @@ module BusinessFlow
|
|
55
58
|
end
|
56
59
|
|
57
60
|
def build(parameter_object)
|
61
|
+
finalize_initializer
|
58
62
|
allocate.tap do |flow|
|
59
63
|
catch(:halt_step) do
|
60
64
|
flow.send(:_business_flow_dsl_initialize,
|
61
|
-
ParameterObject.new(parameter_object)
|
65
|
+
ParameterObject.new(parameter_object))
|
62
66
|
end
|
63
67
|
end
|
64
68
|
end
|
@@ -82,21 +86,48 @@ module BusinessFlow
|
|
82
86
|
end
|
83
87
|
|
84
88
|
def result_from(flow)
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
89
|
+
finalize_result_provider
|
90
|
+
# We use instance_variable_get here instead of making it part of
|
91
|
+
# from_flow to ensure that we do not create the errors object unless
|
92
|
+
# we need it.
|
93
|
+
result = const_get(:Result).new(flow.instance_variable_get(:@errors))
|
94
|
+
result.from_flow(flow) if @result_copy
|
95
|
+
result
|
96
|
+
end
|
97
|
+
|
98
|
+
def finalize_result_provider
|
99
|
+
return if @finalized_result_provider || !@result_copy
|
100
|
+
const_get(:Result).class_eval "#{@result_copy}\nend", __FILE__, __LINE__
|
101
|
+
@finalized_result_provider = true
|
102
|
+
end
|
103
|
+
|
104
|
+
def needs_code
|
105
|
+
needs.map do |need|
|
106
|
+
%(if #{need}.nil?
|
107
|
+
errors[:#{need}] << 'must not be nil'
|
108
|
+
throw :halt_step
|
109
|
+
end
|
110
|
+
)
|
111
|
+
end.join("\n")
|
112
|
+
end
|
113
|
+
|
114
|
+
def finalize_initializer
|
115
|
+
return if @finalized_initializer
|
116
|
+
class_eval %{
|
117
|
+
private def _business_flow_dsl_initialize(parameter_object)
|
118
|
+
@parameter_object = parameter_object
|
119
|
+
#{needs_code}
|
120
|
+
initialize
|
121
|
+
end
|
122
|
+
}, __FILE__, __LINE__ - 6
|
123
|
+
@finalized_initializer = true
|
90
124
|
end
|
91
125
|
end
|
92
126
|
|
93
127
|
RESULT_DEF = %(
|
94
128
|
class Result
|
95
|
-
def initialize(errors
|
129
|
+
def initialize(errors)
|
96
130
|
@errors = errors
|
97
|
-
provides.each do |(name, value)|
|
98
|
-
instance_variable_set("@" + name.to_s, value)
|
99
|
-
end
|
100
131
|
end
|
101
132
|
|
102
133
|
def errors
|
@@ -121,9 +152,20 @@ module BusinessFlow
|
|
121
152
|
end
|
122
153
|
).freeze
|
123
154
|
|
155
|
+
# Provides the minimum necessary methods to support the use of
|
156
|
+
# ActiveModel::Errors
|
157
|
+
module ErrorSupport
|
158
|
+
def human_attribute_name(key, _opts = {})
|
159
|
+
key
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# :reek:ManualDispatch I have no need to actually call human_attribute_name,
|
164
|
+
# I just need to know if I have to provide my own.
|
124
165
|
def self.included(klass)
|
125
166
|
klass.extend(ClassMethods)
|
126
167
|
klass.class_eval RESULT_DEF, __FILE__, __LINE__
|
168
|
+
klass.extend(ErrorSupport) unless klass.respond_to?(:human_attribute_name)
|
127
169
|
end
|
128
170
|
|
129
171
|
attr_reader :parameter_object
|
data/lib/business_flow/step.rb
CHANGED
@@ -35,13 +35,10 @@ module BusinessFlow
|
|
35
35
|
# Represents the result of a step, and allows setting response values on
|
36
36
|
# an object, and merging error data into the same object.
|
37
37
|
class Result
|
38
|
-
# :reek:ManualDispatch Checking respond_to? is signficantly faster than
|
39
|
-
# eating the NoMethodError when grabbing our error object.
|
40
38
|
def initialize(result, output_map, output_callable)
|
41
39
|
@result = result
|
42
40
|
@output_map = output_map
|
43
41
|
@output_callable = output_callable
|
44
|
-
@result_errors = result.respond_to?(:errors) ? result.errors : nil
|
45
42
|
end
|
46
43
|
|
47
44
|
def merge_into(object)
|
@@ -53,8 +50,10 @@ module BusinessFlow
|
|
53
50
|
true
|
54
51
|
end
|
55
52
|
|
53
|
+
# :reek:ManualDispatch Checking respond_to? is signficantly faster than
|
54
|
+
# eating the NoMethodError when grabbing our error object.
|
56
55
|
def errors?
|
57
|
-
@
|
56
|
+
@result.respond_to?(:errors?) ? @result.errors? : false
|
58
57
|
end
|
59
58
|
|
60
59
|
def output
|
@@ -73,8 +72,8 @@ module BusinessFlow
|
|
73
72
|
private
|
74
73
|
|
75
74
|
def merge_errors_into(object)
|
76
|
-
return
|
77
|
-
@
|
75
|
+
return unless errors?
|
76
|
+
@result.errors.each do |attribute, message|
|
78
77
|
attribute = "#{@result.class.name.underscore}.#{attribute}"
|
79
78
|
(object.errors[attribute] << message).uniq!
|
80
79
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: business_flow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Scarborough
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-02-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|