business_flow 0.10.0 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|