rule_box 0.1.3 → 0.2.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 +7 -1
- data/Gemfile.lock +45 -14
- data/README.pt-br.md +47 -14
- data/lib/rule_box/execution_hook.rb +69 -0
- data/lib/rule_box/facade.rb +202 -146
- data/lib/rule_box/mapper.rb +45 -46
- data/lib/rule_box/method_helper.rb +31 -0
- data/lib/rule_box/strategy.rb +30 -30
- data/lib/rule_box/use_case_base.rb +43 -0
- data/lib/rule_box/version.rb +1 -1
- data/lib/rule_box.rb +16 -4
- data/rule_box.gemspec +3 -1
- metadata +7 -10
- data/.gitignore +0 -15
- data/.rspec +0 -3
- data/lib/rule_box/getter.rb +0 -71
- data/lib/rule_box/hash.rb +0 -11
- data/lib/rule_box/proxy.rb +0 -5
- data/lib/rule_box/util.rb +0 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 27b80b3f8ec0341fbd5540a97820428a7473fb2efe3bc6d9120f485cd481c878
|
|
4
|
+
data.tar.gz: 4b44f91e618f1e77e830bb9853d9b1fc6cd066aea51505b04491a3684f866b53
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ad5848afa5b2b38485f7a4eff85dccca01e8f67fea7bbe42516b23c6e57a0c8bfec265881fcc14783297740bcbf611c2d8feb8ec10c489a13f4bfbe43e1e5ab5
|
|
7
|
+
data.tar.gz: 1d597a2071d512d353a2b0c0a8d9e5e301297a4d447c054c72ca6286d489452bdfe0966a35e4ce7deb3b16366f2b34aa105a3b727b4ef06cc4f3dc899ccdac23
|
data/Gemfile
CHANGED
|
@@ -6,4 +6,10 @@ source 'https://rubygems.org'
|
|
|
6
6
|
gemspec
|
|
7
7
|
|
|
8
8
|
gem 'rake', '~> 12.0'
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
group :development, :test do
|
|
11
|
+
gem 'byebug', '~> 11.1', '>= 11.1.3'
|
|
12
|
+
gem 'rspec', '~> 3.0'
|
|
13
|
+
gem 'rubocop', '~> 1.28', '>= 1.28.2', require: false
|
|
14
|
+
gem 'simplecov', '~> 0.21.2', require: false
|
|
15
|
+
end
|
data/Gemfile.lock
CHANGED
|
@@ -1,34 +1,65 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
rule_box (0.
|
|
4
|
+
rule_box (0.2.0)
|
|
5
5
|
|
|
6
6
|
GEM
|
|
7
7
|
remote: https://rubygems.org/
|
|
8
8
|
specs:
|
|
9
|
-
|
|
9
|
+
ast (2.4.2)
|
|
10
|
+
byebug (11.1.3)
|
|
11
|
+
diff-lcs (1.5.0)
|
|
12
|
+
docile (1.4.0)
|
|
13
|
+
parallel (1.22.1)
|
|
14
|
+
parser (3.1.2.0)
|
|
15
|
+
ast (~> 2.4.1)
|
|
16
|
+
rainbow (3.1.1)
|
|
10
17
|
rake (12.3.3)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
rspec-
|
|
15
|
-
|
|
16
|
-
rspec-
|
|
17
|
-
rspec-
|
|
18
|
+
regexp_parser (2.4.0)
|
|
19
|
+
rexml (3.2.5)
|
|
20
|
+
rspec (3.11.0)
|
|
21
|
+
rspec-core (~> 3.11.0)
|
|
22
|
+
rspec-expectations (~> 3.11.0)
|
|
23
|
+
rspec-mocks (~> 3.11.0)
|
|
24
|
+
rspec-core (3.11.0)
|
|
25
|
+
rspec-support (~> 3.11.0)
|
|
26
|
+
rspec-expectations (3.11.0)
|
|
18
27
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
19
|
-
rspec-support (~> 3.
|
|
20
|
-
rspec-mocks (3.
|
|
28
|
+
rspec-support (~> 3.11.0)
|
|
29
|
+
rspec-mocks (3.11.1)
|
|
21
30
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
22
|
-
rspec-support (~> 3.
|
|
23
|
-
rspec-support (3.
|
|
31
|
+
rspec-support (~> 3.11.0)
|
|
32
|
+
rspec-support (3.11.0)
|
|
33
|
+
rubocop (1.29.0)
|
|
34
|
+
parallel (~> 1.10)
|
|
35
|
+
parser (>= 3.1.0.0)
|
|
36
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
37
|
+
regexp_parser (>= 1.8, < 3.0)
|
|
38
|
+
rexml (>= 3.2.5, < 4.0)
|
|
39
|
+
rubocop-ast (>= 1.17.0, < 2.0)
|
|
40
|
+
ruby-progressbar (~> 1.7)
|
|
41
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
|
42
|
+
rubocop-ast (1.17.0)
|
|
43
|
+
parser (>= 3.1.1.0)
|
|
44
|
+
ruby-progressbar (1.11.0)
|
|
45
|
+
simplecov (0.21.2)
|
|
46
|
+
docile (~> 1.1)
|
|
47
|
+
simplecov-html (~> 0.11)
|
|
48
|
+
simplecov_json_formatter (~> 0.1)
|
|
49
|
+
simplecov-html (0.12.3)
|
|
50
|
+
simplecov_json_formatter (0.1.4)
|
|
51
|
+
unicode-display_width (2.1.0)
|
|
24
52
|
|
|
25
53
|
PLATFORMS
|
|
26
54
|
ruby
|
|
27
55
|
|
|
28
56
|
DEPENDENCIES
|
|
57
|
+
byebug (~> 11.1, >= 11.1.3)
|
|
29
58
|
rake (~> 12.0)
|
|
30
59
|
rspec (~> 3.0)
|
|
60
|
+
rubocop (~> 1.28, >= 1.28.2)
|
|
31
61
|
rule_box!
|
|
62
|
+
simplecov (~> 0.21.2)
|
|
32
63
|
|
|
33
64
|
BUNDLED WITH
|
|
34
|
-
2.
|
|
65
|
+
2.3.13
|
data/README.pt-br.md
CHANGED
|
@@ -59,7 +59,7 @@ Existem alguns *helpers* na classe *Strategy* que irão ajudá-lo.
|
|
|
59
59
|
|
|
60
60
|
```ruby
|
|
61
61
|
strategy.model # Retorna o "Model"
|
|
62
|
-
strategy.set_status # Seta o valor
|
|
62
|
+
strategy.set_status # Seta o valor status: [:red, :yellow, :green]
|
|
63
63
|
strategy.add_error # Adiciona uma mensagem de erro
|
|
64
64
|
```
|
|
65
65
|
|
|
@@ -92,7 +92,7 @@ class User
|
|
|
92
92
|
attr_accessor :name
|
|
93
93
|
|
|
94
94
|
# lista de regras de negócio
|
|
95
|
-
|
|
95
|
+
rules Rules::CheckName
|
|
96
96
|
|
|
97
97
|
end
|
|
98
98
|
```
|
|
@@ -103,21 +103,21 @@ require 'rule_box/facade'
|
|
|
103
103
|
|
|
104
104
|
user = User.new
|
|
105
105
|
facade = Rulebox::Facade.new
|
|
106
|
-
facade.
|
|
106
|
+
facade.exec user
|
|
107
107
|
puts facade.status # :red
|
|
108
108
|
puts facade.errors # ["Nome não pode ficar em branco"]
|
|
109
109
|
|
|
110
110
|
user = User.new
|
|
111
111
|
user.name = 'Ana'
|
|
112
112
|
facade = Rulebox::Facade.new
|
|
113
|
-
facade.
|
|
113
|
+
facade.exec user
|
|
114
114
|
puts facade.status # :red
|
|
115
115
|
puts facade.errors # ["Nome deve conter pelo menos 4 caracteres"]
|
|
116
116
|
|
|
117
117
|
user = User.new
|
|
118
118
|
user.name = 'Alex'
|
|
119
119
|
facade = Rulebox::Facade.new
|
|
120
|
-
facade.
|
|
120
|
+
facade.exec user
|
|
121
121
|
puts facade.status # :green
|
|
122
122
|
puts facade.errors # []
|
|
123
123
|
|
|
@@ -167,35 +167,68 @@ class User
|
|
|
167
167
|
include RuleBox::Mapper
|
|
168
168
|
attr_accessor :name, :age
|
|
169
169
|
|
|
170
|
-
|
|
170
|
+
rules Rules::CheckName, Rules::CheckAge, Rules::SaveModel
|
|
171
171
|
|
|
172
172
|
end
|
|
173
173
|
|
|
174
174
|
```
|
|
175
175
|
|
|
176
176
|
|
|
177
|
-
##
|
|
177
|
+
## Hooks
|
|
178
|
+
|
|
179
|
+
Existem alguns hooks que podem auxiliar na chamadas das regras de negócio
|
|
180
|
+
|
|
181
|
+
| Hook | Descrição |
|
|
182
|
+
|------------------|----------------------------------|
|
|
183
|
+
| after_rule | depois de cada regra |
|
|
184
|
+
| after_rules | depois de todas as regras |
|
|
185
|
+
| around_rule | na execução de cada regra |
|
|
186
|
+
| around_rules | na execução de todas as regras |
|
|
187
|
+
| customize_result | customiza o retorno do resultado |
|
|
188
|
+
| before_rule | antes de cada regra |
|
|
189
|
+
| before_rules | antes de todas as regras |
|
|
190
|
+
| rescue_from | captura uma exeção |
|
|
191
|
+
|
|
192
|
+
Exemplo
|
|
193
|
+
```ruby
|
|
194
|
+
|
|
195
|
+
User.before_rules { puts 'before all' }
|
|
196
|
+
User.before_rule do |facade|
|
|
197
|
+
puts 'before'
|
|
198
|
+
puts facade.steps.last
|
|
199
|
+
end
|
|
200
|
+
User.after_rule do |facade|
|
|
201
|
+
puts facade.steps.last
|
|
202
|
+
puts 'after'
|
|
203
|
+
end
|
|
204
|
+
User.before_rules { puts 'after all' }
|
|
178
205
|
|
|
179
|
-
Uma vez no modo de desenvolvimento, ele pode exibir as etapas (steps) que ocorreram no Facade.
|
|
180
206
|
|
|
181
|
-
```ruby
|
|
182
207
|
user = User.new
|
|
183
208
|
user.name = 'Carlos'
|
|
184
209
|
user.age = 19
|
|
185
210
|
|
|
186
211
|
facade = RuleBox::Facade.new
|
|
187
|
-
facade.
|
|
188
|
-
facade.insert user
|
|
212
|
+
facade.exec user
|
|
189
213
|
|
|
190
214
|
# Saída do Log
|
|
191
|
-
#
|
|
192
|
-
#
|
|
215
|
+
# before all
|
|
216
|
+
# before
|
|
193
217
|
# [2020-07-29T08:09:00.212-03:00] executing of rule: Rules::CheckName.
|
|
218
|
+
# [2020-07-29T08:09:00.212-03:00] executing of rule: Rules::CheckName.
|
|
219
|
+
# after
|
|
220
|
+
# before
|
|
221
|
+
# [2020-07-29T08:09:00.212-03:00] executing of rule: Rules::CheckAge.
|
|
194
222
|
# [2020-07-29T08:09:00.212-03:00] executing of rule: Rules::CheckAge.
|
|
223
|
+
# after
|
|
224
|
+
# before
|
|
195
225
|
# [2020-07-29T08:09:00.212-03:00] executing of rule: Rules::SaveModel.
|
|
196
|
-
# [2020-07-29T08:09:00.212-03:00]
|
|
226
|
+
# [2020-07-29T08:09:00.212-03:00] executing of rule: Rules::SaveModel.
|
|
227
|
+
# after
|
|
228
|
+
# after all
|
|
197
229
|
```
|
|
198
230
|
|
|
231
|
+
|
|
199
232
|
## License
|
|
200
233
|
|
|
201
234
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuleBox
|
|
4
|
+
module ExecutionHook
|
|
5
|
+
def self.included(base)
|
|
6
|
+
base.extend ClassMethods
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
module ClassMethods
|
|
10
|
+
new_hooks = %i[
|
|
11
|
+
after_rule after_rules around_rule around_rules
|
|
12
|
+
customize_result
|
|
13
|
+
before_rule before_rules
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
new_hooks.each do |rule|
|
|
17
|
+
define_method rule do |&block|
|
|
18
|
+
hooks[rule] = block
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def call_hook(type, arg = nil)
|
|
23
|
+
block = hooks[type.to_sym]
|
|
24
|
+
return nil unless block.is_a? Proc
|
|
25
|
+
|
|
26
|
+
block.call(arg)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def clear_hooks!
|
|
30
|
+
@rescue_handlers = []
|
|
31
|
+
@hooks = {}
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def has_hook?(name)
|
|
35
|
+
hooks[name.to_sym].is_a? Proc
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def rescue_from(*klasses, &block)
|
|
39
|
+
klasses.each do |klass|
|
|
40
|
+
match = klass < Exception || klass == Exception
|
|
41
|
+
raise ArgumentError, "#{klass.inspect} must be an Exception class" unless match
|
|
42
|
+
|
|
43
|
+
rescue_handlers.concat [[klass, block]]
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def rescue_handlers
|
|
48
|
+
@rescue_handlers ||= []
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def resolve_exception!(facade)
|
|
52
|
+
rescue_handlers.each do |exception, block|
|
|
53
|
+
next unless facade.exception.is_a? exception
|
|
54
|
+
|
|
55
|
+
block.call facade
|
|
56
|
+
return true
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
nil
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
def hooks
|
|
65
|
+
@hooks ||= {}
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
data/lib/rule_box/facade.rb
CHANGED
|
@@ -1,201 +1,257 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
3
|
+
module RuleBox
|
|
4
|
+
class Facade
|
|
5
|
+
include RuleBox::MethodHelper
|
|
6
|
+
include RuleBox::ExecutionHook
|
|
7
|
+
|
|
8
|
+
attr_reader :entity, :exception, :strategies, :current_strategy, :current_method, :bucket, :executed, :last_result,
|
|
9
|
+
:status
|
|
10
|
+
|
|
11
|
+
attr_clones :errors, :steps
|
|
12
|
+
|
|
13
|
+
def initialize(**dependencies)
|
|
14
|
+
set_dependencies! dependencies
|
|
15
|
+
@executed = false
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def add_error(msg)
|
|
19
|
+
if msg.is_a? Array
|
|
20
|
+
msg.each { |message| add_error(message) }
|
|
21
|
+
else
|
|
22
|
+
@errors << msg
|
|
19
23
|
end
|
|
20
24
|
end
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
def exec(method = :perform, entity, **args)
|
|
27
|
+
perform method, entity, **args
|
|
28
|
+
end
|
|
23
29
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
end
|
|
30
|
+
def get(key)
|
|
31
|
+
keys[key.to_s].clone
|
|
32
|
+
end
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
end
|
|
34
|
+
def run
|
|
35
|
+
return unless @next_run
|
|
32
36
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
send @next_run
|
|
38
|
+
true
|
|
39
|
+
end
|
|
36
40
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
def set_status(status)
|
|
42
|
+
@status = status
|
|
43
|
+
end
|
|
40
44
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
def instance_values
|
|
46
|
+
hash = {
|
|
47
|
+
current_strategy: @current_strategy&.instance_values,
|
|
48
|
+
strategies: (@strategies || []).map(&:instance_values)
|
|
49
|
+
}
|
|
44
50
|
|
|
45
|
-
|
|
46
|
-
@_current_class ||=
|
|
47
|
-
if model.nil?
|
|
48
|
-
nil
|
|
49
|
-
elsif model.is_a?(Class) || model.is_a?(Module)
|
|
50
|
-
model
|
|
51
|
-
elsif model.is_a?(Symbol) || model.is_a?(String)
|
|
52
|
-
Object.const_get RuleBox::Util.camelize(model.to_s)
|
|
53
|
-
else
|
|
54
|
-
Object.const_get model.class.name
|
|
55
|
-
end
|
|
56
|
-
end
|
|
51
|
+
keys.each { |k, v| hash[k.to_sym] = v.clone }
|
|
57
52
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
53
|
+
%i[
|
|
54
|
+
entity exception current_class current_method bucket
|
|
55
|
+
executed last_result status errors steps
|
|
56
|
+
].each { |key| hash[key] = send(key).clone }
|
|
57
|
+
|
|
58
|
+
hash
|
|
63
59
|
end
|
|
64
|
-
attrs
|
|
65
|
-
end
|
|
66
60
|
|
|
67
|
-
|
|
68
|
-
JSON.generate(as_json(args), args)
|
|
69
|
-
end
|
|
61
|
+
private
|
|
70
62
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
63
|
+
def add_step(value)
|
|
64
|
+
new_value = "[#{DateTime.now.strftime('%FT%T.%L%:z')}] #{value}"
|
|
65
|
+
@steps << new_value
|
|
66
|
+
end
|
|
74
67
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
68
|
+
def around(around_method, current_method)
|
|
69
|
+
@next_run = current_method
|
|
70
|
+
hooks.each { |hook| hook.call_hook around_method, self }
|
|
71
|
+
@next_run = nil
|
|
72
|
+
end
|
|
78
73
|
|
|
79
|
-
|
|
74
|
+
def build_bucket
|
|
75
|
+
{}
|
|
76
|
+
end
|
|
80
77
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
78
|
+
def check_executed!
|
|
79
|
+
raise 'Process already executed' if @executed
|
|
80
|
+
end
|
|
84
81
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
execute(method, model, args)
|
|
88
|
-
end
|
|
82
|
+
def check_strategies!(class_strategies)
|
|
83
|
+
raise "class [#{current_class}] without mapped rules to [#{current_method}]'" if class_strategies.empty?
|
|
89
84
|
|
|
90
|
-
|
|
91
|
-
|
|
85
|
+
classes = class_strategies.reject { |strategy| strategy < RuleBox::Strategy }
|
|
86
|
+
unless classes.size.zero?
|
|
87
|
+
raise "class [#{classes.map(&:name).join(', ')}] must extends RuleBox::Strategy or your subclass."
|
|
88
|
+
end
|
|
89
|
+
end
|
|
92
90
|
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
def current_class
|
|
92
|
+
entity.class
|
|
93
|
+
end
|
|
95
94
|
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
def execute_all
|
|
96
|
+
hooks.each { |h| h.call_hook(:before_rules, self) }
|
|
98
97
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
98
|
+
if hooks.any? { |h| h.has_hook? :around_rules }
|
|
99
|
+
around :around_rules, :execute_strategies
|
|
100
|
+
else
|
|
101
|
+
execute_strategies
|
|
102
|
+
end
|
|
103
|
+
hooks.each { |h| h.call_hook(:after_rules, self) }
|
|
104
|
+
end
|
|
105
105
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
@_current_method = method
|
|
109
|
-
class_name = _current_class
|
|
110
|
-
@errors = []
|
|
111
|
-
@steps = []
|
|
106
|
+
def execute_one
|
|
107
|
+
hooks.each { |h| h.call_hook(:before_rule, self) }
|
|
112
108
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
109
|
+
if hooks.any? { |h| h.has_hook? :around_rule }
|
|
110
|
+
around :around_rule, :execute_strategy
|
|
111
|
+
else
|
|
112
|
+
execute_strategy
|
|
113
|
+
end
|
|
114
|
+
hooks.each { |h| h.call_hook(:after_rule, self) }
|
|
117
115
|
end
|
|
118
116
|
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
def execute_strategies
|
|
118
|
+
@strategies.each do |strategy|
|
|
119
|
+
@current_strategy = strategy
|
|
120
|
+
execute_one
|
|
121
|
+
break if status == failure_status
|
|
122
|
+
end
|
|
123
|
+
rescue Exception => e
|
|
124
|
+
@exception = e
|
|
125
|
+
ensure
|
|
126
|
+
add_step 'finalized the process on the facade.'
|
|
127
|
+
end
|
|
121
128
|
|
|
122
|
-
|
|
123
|
-
|
|
129
|
+
def execute_strategy
|
|
130
|
+
add_step "executing of rule: #{@current_strategy.class.name}."
|
|
124
131
|
|
|
125
|
-
|
|
126
|
-
add_step "executing of rule: #{strategy.class.name}."
|
|
127
|
-
strategy.process
|
|
132
|
+
strategy_method = @current_strategy.method(:perform)
|
|
128
133
|
|
|
129
|
-
|
|
134
|
+
@last_result =
|
|
135
|
+
if strategy_method.parameters.empty?
|
|
136
|
+
strategy_method.call
|
|
137
|
+
else
|
|
138
|
+
strategy_method.call(@last_result)
|
|
139
|
+
end
|
|
130
140
|
end
|
|
131
|
-
rescue Exception => e
|
|
132
|
-
errors << settings.default_error_message
|
|
133
|
-
@status = :red
|
|
134
|
-
block = settings.resolve
|
|
135
|
-
block.call(e, RuleBox::Proxy.new(self)) if block.is_a? Proc
|
|
136
|
-
ensure
|
|
137
|
-
add_step 'finalized the process on the facade.'
|
|
138
|
-
return self
|
|
139
|
-
end
|
|
140
141
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
def failure_status
|
|
143
|
+
:red
|
|
144
|
+
end
|
|
144
145
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
steps << new_value
|
|
149
|
-
end
|
|
146
|
+
def has_hook?(hook_method)
|
|
147
|
+
entity.class.has_hook? hook_method
|
|
148
|
+
end
|
|
150
149
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
150
|
+
def hooks
|
|
151
|
+
[current_class, self.class, RuleBox]
|
|
152
|
+
end
|
|
154
153
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
154
|
+
def initialize_variables!(method, entity, args)
|
|
155
|
+
@executed = true
|
|
156
|
+
@entity = entity
|
|
157
|
+
@current_method = method
|
|
158
|
+
@status = start_status
|
|
159
|
+
@bucket = build_bucket
|
|
160
|
+
@steps = []
|
|
161
|
+
@errors = []
|
|
162
|
+
args.each { |key, value| bucket[key] = value }
|
|
163
|
+
end
|
|
158
164
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
165
|
+
def initialize_strategies!(method, entity)
|
|
166
|
+
class_strategies = entity.class.strategies(method)
|
|
167
|
+
check_strategies!(class_strategies)
|
|
168
|
+
@strategies = class_strategies.map { |klass| klass.new(self) }
|
|
169
|
+
end
|
|
162
170
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
def configure
|
|
166
|
-
yield(settings) if block_given?
|
|
171
|
+
def keys
|
|
172
|
+
@keys ||= {}
|
|
167
173
|
end
|
|
168
174
|
|
|
169
|
-
def
|
|
170
|
-
|
|
175
|
+
def perform(method, entity, **args)
|
|
176
|
+
check_executed!
|
|
177
|
+
initialize_variables!(method, entity, args)
|
|
178
|
+
initialize_strategies!(method, entity)
|
|
179
|
+
add_step "initialize { method: #{method}, entity: #{current_class}, rules: #{@strategies.count} }"
|
|
180
|
+
execute_all
|
|
181
|
+
resolve_exception!
|
|
182
|
+
return_result
|
|
171
183
|
end
|
|
172
184
|
|
|
173
|
-
def
|
|
174
|
-
|
|
185
|
+
def return_result
|
|
186
|
+
result = nil
|
|
187
|
+
hooks.each do |hook|
|
|
188
|
+
result = hook.call_hook(:customize_result, self)
|
|
189
|
+
break if result
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
result || last_result
|
|
175
193
|
end
|
|
176
194
|
|
|
177
|
-
|
|
195
|
+
def resolve_exception!
|
|
196
|
+
return unless @exception.is_a?(Exception)
|
|
178
197
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
attr_accessor :show_steps
|
|
198
|
+
resolved = hooks.map { |hook| hook.resolve_exception!(self) }.compact
|
|
199
|
+
raise @exception if resolved.length.zero?
|
|
200
|
+
end
|
|
183
201
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
end
|
|
202
|
+
def set(key, value)
|
|
203
|
+
keys[key.to_s] = value
|
|
204
|
+
end
|
|
188
205
|
|
|
206
|
+
def set_dependencies!(dependencies)
|
|
207
|
+
self.class.set_dependencies(self, dependencies)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def start_status
|
|
211
|
+
:green
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# class Methods
|
|
215
|
+
class << self
|
|
189
216
|
def add_dependency(key, &block)
|
|
190
217
|
dependencies[key.to_sym] = block
|
|
191
218
|
end
|
|
192
219
|
|
|
193
|
-
def
|
|
194
|
-
|
|
220
|
+
def configure(&block)
|
|
221
|
+
block.call(self)
|
|
195
222
|
end
|
|
196
223
|
|
|
197
|
-
def
|
|
198
|
-
@
|
|
224
|
+
def clear_configuration!
|
|
225
|
+
@dependencies = {}
|
|
226
|
+
clear_hooks!
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def set_dependencies(facade, dependencies)
|
|
230
|
+
errors = []
|
|
231
|
+
|
|
232
|
+
self.dependencies.each do |key, block|
|
|
233
|
+
if dependencies.key? key
|
|
234
|
+
value = dependencies[key]
|
|
235
|
+
block&.call(value, errors)
|
|
236
|
+
facade.send(:set, key, value)
|
|
237
|
+
else
|
|
238
|
+
errors << "missing keyword: #{key}"
|
|
239
|
+
end
|
|
240
|
+
rescue StandardError => e
|
|
241
|
+
errors << e.message
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
raise errors.join("\n") unless errors.empty?
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def use_case!
|
|
248
|
+
define_method(:use_case) { entity }
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
private
|
|
252
|
+
|
|
253
|
+
def dependencies
|
|
254
|
+
@dependencies ||= {}
|
|
199
255
|
end
|
|
200
256
|
end
|
|
201
257
|
end
|
data/lib/rule_box/mapper.rb
CHANGED
|
@@ -1,62 +1,61 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module RuleBox
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def rules_of_update(*rules)
|
|
19
|
-
add_rules :update, rules
|
|
3
|
+
module RuleBox
|
|
4
|
+
module Mapper
|
|
5
|
+
extend RuleBox::ExecutionHook
|
|
6
|
+
|
|
7
|
+
if const_defined? 'ActiveSupport::Concern'
|
|
8
|
+
# to Rails project
|
|
9
|
+
extend ActiveSupport::Concern
|
|
10
|
+
included { include RuleBox::ExecutionHook }
|
|
11
|
+
else
|
|
12
|
+
def self.included(klass)
|
|
13
|
+
klass.include RuleBox::ExecutionHook
|
|
14
|
+
klass.extend ClassMethods
|
|
15
|
+
mapped << klass
|
|
16
|
+
end
|
|
20
17
|
end
|
|
21
18
|
|
|
22
|
-
def
|
|
23
|
-
|
|
19
|
+
def self.mapped
|
|
20
|
+
@mapped ||= Set.new
|
|
24
21
|
end
|
|
25
22
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
module ClassMethods
|
|
24
|
+
def rules(*rules)
|
|
25
|
+
add_rules :perform, rules
|
|
26
|
+
end
|
|
29
27
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
def rules_of(method, *rules)
|
|
29
|
+
add_rules method.to_sym, rules
|
|
30
|
+
end
|
|
33
31
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
def strategies(method)
|
|
33
|
+
current_rules[method]
|
|
34
|
+
end
|
|
37
35
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
36
|
+
def show_strategies
|
|
37
|
+
current_rules.map do |method, strategies|
|
|
38
|
+
{
|
|
39
|
+
method: method,
|
|
40
|
+
strategies: strategies.map do |strategy|
|
|
41
|
+
{
|
|
42
|
+
name: strategy.name,
|
|
43
|
+
description: strategy.description
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
}
|
|
47
|
+
end
|
|
49
48
|
end
|
|
50
|
-
end
|
|
51
49
|
|
|
52
|
-
|
|
50
|
+
private
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
def add_rules(method, rules)
|
|
53
|
+
current_rules[method] = rules
|
|
54
|
+
end
|
|
57
55
|
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
def current_rules
|
|
57
|
+
@current_rules ||= {}
|
|
58
|
+
end
|
|
60
59
|
end
|
|
61
60
|
end
|
|
62
61
|
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuleBox
|
|
4
|
+
module MethodHelper
|
|
5
|
+
def self.included(klass)
|
|
6
|
+
klass.extend(ClassMethods)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
module ClassMethods
|
|
10
|
+
def attr_clones(*methods, to: nil)
|
|
11
|
+
methods.each do |method|
|
|
12
|
+
define_method(method) do
|
|
13
|
+
resource = to || self
|
|
14
|
+
resource.instance_variable_get("@#{method}").clone
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def delegate_methods(*methods, to:, set_private: false)
|
|
20
|
+
methods.each do |method|
|
|
21
|
+
define_method method do |*rest, **restkey|
|
|
22
|
+
object = send to
|
|
23
|
+
object.send method, *rest, **restkey
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private method if set_private
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/rule_box/strategy.rb
CHANGED
|
@@ -1,45 +1,45 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
module RuleBox
|
|
4
|
+
class Strategy
|
|
5
|
+
include RuleBox::MethodHelper
|
|
6
|
+
attr_reader :facade
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
delegate_methods :add_error, :current_method, :bucket, :entity, :errors,
|
|
9
|
+
:executed, :last_result, :get, :set_status, :status, :steps, :use_case,
|
|
10
|
+
to: :facade, set_private: true
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
def initialize(facade = nil)
|
|
13
|
+
@facade = facade
|
|
14
|
+
end
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@facade.errors.concat(msg)
|
|
17
|
-
else
|
|
18
|
-
@facade.errors << msg
|
|
16
|
+
def perform
|
|
17
|
+
raise 'Must implement this method'
|
|
19
18
|
end
|
|
20
|
-
end
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
def instance_values
|
|
21
|
+
hash = { strategy_name: self.class.name }
|
|
22
|
+
instance_variables.each do |name|
|
|
23
|
+
next if name == :@facade
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
end
|
|
25
|
+
hash[name[1..]] = instance_variable_get(name)
|
|
26
|
+
end
|
|
29
27
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
end
|
|
28
|
+
hash
|
|
29
|
+
end
|
|
33
30
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
end
|
|
31
|
+
class << self
|
|
32
|
+
attr_reader :description
|
|
37
33
|
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
def desc(description)
|
|
35
|
+
@description = description
|
|
36
|
+
end
|
|
40
37
|
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
def perform(&block)
|
|
39
|
+
define_method :perform do |result = nil|
|
|
40
|
+
instance_exec(result, &block)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuleBox
|
|
4
|
+
class UseCaseBase
|
|
5
|
+
include RuleBox::Mapper
|
|
6
|
+
|
|
7
|
+
def initialize(**args)
|
|
8
|
+
args.each do |key, value|
|
|
9
|
+
key = key.to_s
|
|
10
|
+
attributes[key] = value if attribute_names.include? key
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def to_s
|
|
15
|
+
names = self.class.name.split('::').reverse.join
|
|
16
|
+
names.gsub(/::/, '/')
|
|
17
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
|
18
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
|
19
|
+
.tr('-', '_')
|
|
20
|
+
.downcase
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def attribute_names
|
|
24
|
+
[]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def attributes
|
|
28
|
+
@attributes ||= {}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class << self
|
|
32
|
+
def attributes(*names)
|
|
33
|
+
names = names.map(&:to_s)
|
|
34
|
+
define_method(:attribute_names) { names }
|
|
35
|
+
|
|
36
|
+
names.each do |name|
|
|
37
|
+
define_method(name) { attributes[name] }
|
|
38
|
+
define_method("#{name}=") { |value| attributes[name] = value }
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
data/lib/rule_box/version.rb
CHANGED
data/lib/rule_box.rb
CHANGED
|
@@ -2,22 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
require 'time'
|
|
4
4
|
require 'json'
|
|
5
|
+
require 'set'
|
|
6
|
+
|
|
7
|
+
require 'rule_box/execution_hook'
|
|
5
8
|
|
|
6
9
|
module RuleBox
|
|
10
|
+
include RuleBox::ExecutionHook
|
|
7
11
|
class Error < StandardError; end
|
|
8
12
|
|
|
9
13
|
class << self
|
|
10
14
|
def show_mapped_classes
|
|
11
15
|
RuleBox::Mapper.mapped.to_a
|
|
12
16
|
end
|
|
17
|
+
|
|
18
|
+
def configure
|
|
19
|
+
block_given? ? yield(settings) : settings
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def settings
|
|
25
|
+
self
|
|
26
|
+
end
|
|
13
27
|
end
|
|
14
28
|
end
|
|
15
29
|
|
|
30
|
+
require 'rule_box/method_helper'
|
|
16
31
|
require 'rule_box/facade'
|
|
17
|
-
require 'rule_box/getter'
|
|
18
|
-
require 'rule_box/hash'
|
|
19
32
|
require 'rule_box/mapper'
|
|
20
|
-
require 'rule_box/proxy'
|
|
21
33
|
require 'rule_box/strategy'
|
|
22
|
-
require 'rule_box/
|
|
34
|
+
require 'rule_box/use_case_base'
|
|
23
35
|
require 'rule_box/version'
|
data/rule_box.gemspec
CHANGED
|
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
|
12
12
|
spec.description = 'This gem is focused in giving a strong and concrete way to manage your business rules, mixing the best of both worlds in Facade and Strategy, bringing you a simplified way to apply these Design Patterns into your project.'
|
|
13
13
|
spec.homepage = 'https://github.com/ralphsbaesso/rule_box'
|
|
14
14
|
spec.license = 'MIT'
|
|
15
|
-
spec.required_ruby_version = Gem::Requirement.new('>=
|
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 3.0.0')
|
|
16
16
|
|
|
17
17
|
# spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
|
|
18
18
|
|
|
@@ -25,6 +25,8 @@ Gem::Specification.new do |spec|
|
|
|
25
25
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
26
26
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
27
27
|
end
|
|
28
|
+
spec.files -= %w[.gitignore .rspec .rspec_status]
|
|
29
|
+
|
|
28
30
|
spec.bindir = 'exe'
|
|
29
31
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
30
32
|
spec.require_paths = ['lib']
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rule_box
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ralph Baesso
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: exe
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2022-08-09 00:00:00.000000000 Z
|
|
13
13
|
dependencies: []
|
|
14
14
|
description: This gem is focused in giving a strong and concrete way to manage your
|
|
15
15
|
business rules, mixing the best of both worlds in Facade and Strategy, bringing
|
|
@@ -21,8 +21,6 @@ executables: []
|
|
|
21
21
|
extensions: []
|
|
22
22
|
extra_rdoc_files: []
|
|
23
23
|
files:
|
|
24
|
-
- ".gitignore"
|
|
25
|
-
- ".rspec"
|
|
26
24
|
- ".travis.yml"
|
|
27
25
|
- CODE_OF_CONDUCT.md
|
|
28
26
|
- Gemfile
|
|
@@ -34,13 +32,12 @@ files:
|
|
|
34
32
|
- bin/console
|
|
35
33
|
- bin/setup
|
|
36
34
|
- lib/rule_box.rb
|
|
35
|
+
- lib/rule_box/execution_hook.rb
|
|
37
36
|
- lib/rule_box/facade.rb
|
|
38
|
-
- lib/rule_box/getter.rb
|
|
39
|
-
- lib/rule_box/hash.rb
|
|
40
37
|
- lib/rule_box/mapper.rb
|
|
41
|
-
- lib/rule_box/
|
|
38
|
+
- lib/rule_box/method_helper.rb
|
|
42
39
|
- lib/rule_box/strategy.rb
|
|
43
|
-
- lib/rule_box/
|
|
40
|
+
- lib/rule_box/use_case_base.rb
|
|
44
41
|
- lib/rule_box/version.rb
|
|
45
42
|
- rule_box.gemspec
|
|
46
43
|
homepage: https://github.com/ralphsbaesso/rule_box
|
|
@@ -57,14 +54,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
57
54
|
requirements:
|
|
58
55
|
- - ">="
|
|
59
56
|
- !ruby/object:Gem::Version
|
|
60
|
-
version:
|
|
57
|
+
version: 3.0.0
|
|
61
58
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
62
59
|
requirements:
|
|
63
60
|
- - ">="
|
|
64
61
|
- !ruby/object:Gem::Version
|
|
65
62
|
version: '0'
|
|
66
63
|
requirements: []
|
|
67
|
-
rubygems_version: 3.
|
|
64
|
+
rubygems_version: 3.2.32
|
|
68
65
|
signing_key:
|
|
69
66
|
specification_version: 4
|
|
70
67
|
summary: RuleBox
|
data/.gitignore
DELETED
data/.rspec
DELETED
data/lib/rule_box/getter.rb
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RuleBox::Getter
|
|
4
|
-
def initialize(facade)
|
|
5
|
-
raise 'Must pass an "RFacade"' unless facade.is_a? RuleBox::Facade
|
|
6
|
-
|
|
7
|
-
@facade = facade
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def model
|
|
11
|
-
model = @facade.model
|
|
12
|
-
if model.is_a?(Class) || model.is_a?(Module)
|
|
13
|
-
model.to_s
|
|
14
|
-
else
|
|
15
|
-
model.clone
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def status
|
|
20
|
-
@facade.status
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def data
|
|
24
|
-
@facade.data.clone
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def bucket
|
|
28
|
-
@facade.bucket.clone
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def errors
|
|
32
|
-
@facade.errors.clone
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def steps
|
|
36
|
-
@facade.steps.clone
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def _current_method
|
|
40
|
-
@facade._current_method
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def executed
|
|
44
|
-
@facade.executed
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def to_json(**args)
|
|
48
|
-
@facade.to_json(args)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def as_json(**options)
|
|
52
|
-
options.key?(:root) ? { self.class.name.to_sym => @facade.attributes } : @facade.attributes
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def to_s
|
|
56
|
-
@facade.as_json(root: true).to_s
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def respond_to_missing?(*several_variants)
|
|
60
|
-
super unless method.to_s.start_with? 'current_'
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
private
|
|
64
|
-
|
|
65
|
-
def method_missing(method)
|
|
66
|
-
super unless method.to_s.start_with? 'current_'
|
|
67
|
-
|
|
68
|
-
keys = @facade.send :keys
|
|
69
|
-
keys[method].clone
|
|
70
|
-
end
|
|
71
|
-
end
|
data/lib/rule_box/hash.rb
DELETED
data/lib/rule_box/proxy.rb
DELETED
data/lib/rule_box/util.rb
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RuleBox::Util
|
|
4
|
-
class << self
|
|
5
|
-
def camelize(string)
|
|
6
|
-
strings = string.split('_')
|
|
7
|
-
new_string = ''
|
|
8
|
-
strings.each do |word|
|
|
9
|
-
new_string += word[0].upcase + word[1..-1]
|
|
10
|
-
end
|
|
11
|
-
new_string.gsub('/', '::')
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|