service_actor 3.1.2 → 3.1.3
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/README.md +26 -25
- data/lib/service_actor/attributable.rb +3 -0
- data/lib/service_actor/core.rb +4 -1
- data/lib/service_actor/error.rb +1 -1
- data/lib/service_actor/nil_checkable.rb +4 -9
- data/lib/service_actor/playable.rb +19 -8
- data/lib/service_actor/result.rb +1 -1
- data/lib/service_actor/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 40bbf17640409642508a6cb2dc7bd7197a49266ae9639c4a97c5cf52a3696ddd
|
|
4
|
+
data.tar.gz: 6b2627086780fcbead6e4ce3feff3565eab1bc5e3181a743296e8a7099e22480
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0af13a24439bbab76ce2ae6ddf57e41b86b34c4f81e7d333650675195ab27d2519385e479bc1c41eee3c61f54253812c7e6579fea47bd7d8d17839d76a9808af
|
|
7
|
+
data.tar.gz: d25a43b1637a9dd1d79c6c0686ccc9bc2bb69dfbf0667c5a8775b1ac3fffab4c3d2233a955a17d676a0ee17b1af1a583449ac39dea220bbc02df3f82e9df6275
|
data/README.md
CHANGED
|
@@ -18,7 +18,7 @@ and controllers thin.
|
|
|
18
18
|
- [Conditions](#conditions)
|
|
19
19
|
- [Allow nil](#allow-nil)
|
|
20
20
|
- [Types](#types)
|
|
21
|
-
- [
|
|
21
|
+
- [Fail](#fail)
|
|
22
22
|
- [Play actors in a sequence](#play-actors-in-a-sequence)
|
|
23
23
|
- [Rollback](#rollback)
|
|
24
24
|
- [Lambdas](#lambdas)
|
|
@@ -103,7 +103,7 @@ class BuildGreeting < Actor
|
|
|
103
103
|
output :greeting
|
|
104
104
|
|
|
105
105
|
def call
|
|
106
|
-
self.greeting =
|
|
106
|
+
self.greeting = "Have a wonderful day!"
|
|
107
107
|
end
|
|
108
108
|
end
|
|
109
109
|
```
|
|
@@ -122,8 +122,8 @@ Inputs can be marked as optional by providing a default:
|
|
|
122
122
|
```rb
|
|
123
123
|
class BuildGreeting < Actor
|
|
124
124
|
input :name
|
|
125
|
-
input :adjective, default:
|
|
126
|
-
input :length_of_time, default: -> { [
|
|
125
|
+
input :adjective, default: "wonderful"
|
|
126
|
+
input :length_of_time, default: -> { ["day", "week", "month"].sample }
|
|
127
127
|
|
|
128
128
|
output :greeting
|
|
129
129
|
|
|
@@ -136,7 +136,7 @@ end
|
|
|
136
136
|
This lets you call the actor without specifying those keys:
|
|
137
137
|
|
|
138
138
|
```rb
|
|
139
|
-
result = BuildGreeting.call(name:
|
|
139
|
+
result = BuildGreeting.call(name: "Jim")
|
|
140
140
|
result.greeting # => "Have a wonderful week Jim!"
|
|
141
141
|
```
|
|
142
142
|
|
|
@@ -149,8 +149,7 @@ result = BuildGreeting.call
|
|
|
149
149
|
|
|
150
150
|
### Conditions
|
|
151
151
|
|
|
152
|
-
You can ensure an input is included in a collection by using `in
|
|
153
|
-
yet):
|
|
152
|
+
You can ensure an input is included in a collection by using `in`:
|
|
154
153
|
|
|
155
154
|
```rb
|
|
156
155
|
class Pay < Actor
|
|
@@ -192,12 +191,12 @@ end
|
|
|
192
191
|
|
|
193
192
|
### Types
|
|
194
193
|
|
|
195
|
-
Sometimes it can help to have a quick way of making sure we didn
|
|
194
|
+
Sometimes it can help to have a quick way of making sure we didn’t mess up our
|
|
196
195
|
inputs.
|
|
197
196
|
|
|
198
197
|
For that you can use the `type` option and giving a class or an array
|
|
199
|
-
of possible classes. If the input or output doesn
|
|
200
|
-
|
|
198
|
+
of possible classes. If the input or output doesn’t match these types, an
|
|
199
|
+
error is raised.
|
|
201
200
|
|
|
202
201
|
```rb
|
|
203
202
|
class UpdateUser < Actor
|
|
@@ -212,10 +211,9 @@ You may also use strings instead of constants, such as `type: 'User'`.
|
|
|
212
211
|
|
|
213
212
|
When using a type condition, `allow_nil` defaults to `false`.
|
|
214
213
|
|
|
215
|
-
###
|
|
214
|
+
### Fail
|
|
216
215
|
|
|
217
|
-
|
|
218
|
-
mark an actor as having failed, use `fail!`:
|
|
216
|
+
To stop the execution and mark an actor as having failed, use `fail!`:
|
|
219
217
|
|
|
220
218
|
```rb
|
|
221
219
|
class UpdateUser
|
|
@@ -225,7 +223,7 @@ class UpdateUser
|
|
|
225
223
|
def call
|
|
226
224
|
user.attributes = attributes
|
|
227
225
|
|
|
228
|
-
fail!(error:
|
|
226
|
+
fail!(error: "Invalid user") unless user.valid?
|
|
229
227
|
|
|
230
228
|
# …
|
|
231
229
|
end
|
|
@@ -235,7 +233,8 @@ end
|
|
|
235
233
|
This will raise an error in your app with the given data added to the result.
|
|
236
234
|
|
|
237
235
|
To test for the success of your actor instead of raising an exception, use
|
|
238
|
-
`.result` instead of `.call
|
|
236
|
+
`.result` instead of `.call`. You can then call `success?` or `failure?` on
|
|
237
|
+
the result.
|
|
239
238
|
|
|
240
239
|
For example in a Rails controller:
|
|
241
240
|
|
|
@@ -253,7 +252,7 @@ class UsersController < ApplicationController
|
|
|
253
252
|
end
|
|
254
253
|
```
|
|
255
254
|
|
|
256
|
-
|
|
255
|
+
The keys you add to `fail!` will be added to the result, for example you could
|
|
257
256
|
do: `fail!(error_type: "validation", error_code: "uv52", …)`.
|
|
258
257
|
|
|
259
258
|
## Play actors in a sequence
|
|
@@ -302,8 +301,8 @@ anything to clean up if they call `fail!`.
|
|
|
302
301
|
|
|
303
302
|
### Lambdas
|
|
304
303
|
|
|
305
|
-
You can use inline actions using lambdas. Inside these lambdas
|
|
306
|
-
|
|
304
|
+
You can use inline actions using lambdas. Inside these lambdas you have access to
|
|
305
|
+
the shared result:
|
|
307
306
|
|
|
308
307
|
```rb
|
|
309
308
|
class Pay < Actor
|
|
@@ -315,15 +314,15 @@ end
|
|
|
315
314
|
```
|
|
316
315
|
|
|
317
316
|
Like in this example, lambdas can be useful for small work or preparing the
|
|
318
|
-
result for the next actors. If you want to do more work before, or
|
|
319
|
-
whole `play`, you can also override the `call` method. For example:
|
|
317
|
+
result for the next actors. If you want to do more work before, after or around
|
|
318
|
+
the whole `play`, you can also override the `call` method. For example:
|
|
320
319
|
|
|
321
320
|
```rb
|
|
322
321
|
class Pay < Actor
|
|
323
322
|
# …
|
|
324
323
|
|
|
325
324
|
def call
|
|
326
|
-
Time.with_timezone(
|
|
325
|
+
Time.with_timezone("Paris") do
|
|
327
326
|
super
|
|
328
327
|
end
|
|
329
328
|
end
|
|
@@ -354,6 +353,8 @@ catch the exception to treat it as an actor failure:
|
|
|
354
353
|
class PlaceOrder < Actor
|
|
355
354
|
fail_on ServiceActor::ArgumentError
|
|
356
355
|
|
|
356
|
+
input :currency, in: ["EUR", "USD"]
|
|
357
|
+
|
|
357
358
|
# …
|
|
358
359
|
end
|
|
359
360
|
```
|
|
@@ -368,11 +369,11 @@ make it easier for you to test your application.
|
|
|
368
369
|
|
|
369
370
|
## Build your own actor
|
|
370
371
|
|
|
371
|
-
If you application already uses
|
|
372
|
-
changing the gem
|
|
372
|
+
If you application already uses a class called “Actor”, you can build your own
|
|
373
|
+
by changing the gem’s require statement:
|
|
373
374
|
|
|
374
375
|
```rb
|
|
375
|
-
gem
|
|
376
|
+
gem "service_actor", require: "service_actor/base"
|
|
376
377
|
```
|
|
377
378
|
|
|
378
379
|
And building your own class to inherit from:
|
|
@@ -387,7 +388,7 @@ end
|
|
|
387
388
|
|
|
388
389
|
This gem is heavily influenced by
|
|
389
390
|
[Interactor](https://github.com/collectiveidea/interactor) ♥.
|
|
390
|
-
Some key differences make
|
|
391
|
+
Some key differences make Actor unique:
|
|
391
392
|
|
|
392
393
|
- Does not [hide errors when an actor fails inside another
|
|
393
394
|
actor](https://github.com/collectiveidea/interactor/issues/170).
|
data/lib/service_actor/core.rb
CHANGED
|
@@ -38,12 +38,15 @@ module ServiceActor
|
|
|
38
38
|
# To implement in your actors.
|
|
39
39
|
def rollback; end
|
|
40
40
|
|
|
41
|
+
# This method is used internally to override behavior on call. Overriding
|
|
42
|
+
# `call` instead would mean that end-users have to call `super` in their
|
|
43
|
+
# actors.
|
|
41
44
|
# :nodoc:
|
|
42
45
|
def _call
|
|
43
46
|
call
|
|
44
47
|
end
|
|
45
48
|
|
|
46
|
-
|
|
49
|
+
protected
|
|
47
50
|
|
|
48
51
|
# Returns the current context from inside an actor.
|
|
49
52
|
attr_reader :result
|
data/lib/service_actor/error.rb
CHANGED
|
@@ -36,15 +36,10 @@ module ServiceActor
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def allow_nil?(options)
|
|
39
|
-
if options.key?(:allow_nil)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
elsif options[:type]
|
|
44
|
-
false
|
|
45
|
-
else
|
|
46
|
-
true
|
|
47
|
-
end
|
|
39
|
+
return options[:allow_nil] if options.key?(:allow_nil)
|
|
40
|
+
return true if options.key?(:default) && options[:default].nil?
|
|
41
|
+
|
|
42
|
+
!options[:type]
|
|
48
43
|
end
|
|
49
44
|
end
|
|
50
45
|
end
|
|
@@ -48,7 +48,7 @@ module ServiceActor
|
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
def rollback
|
|
51
|
-
return unless @played
|
|
51
|
+
return unless defined?(@played)
|
|
52
52
|
|
|
53
53
|
@played.each do |actor|
|
|
54
54
|
next unless actor.respond_to?(:rollback)
|
|
@@ -60,16 +60,27 @@ module ServiceActor
|
|
|
60
60
|
private
|
|
61
61
|
|
|
62
62
|
def play_actor(actor)
|
|
63
|
-
|
|
64
|
-
actor
|
|
65
|
-
actor.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
63
|
+
play_service_actor(actor) ||
|
|
64
|
+
play_interactor(actor) ||
|
|
65
|
+
actor.call(result)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def play_service_actor(actor)
|
|
69
|
+
return unless actor.is_a?(Class)
|
|
70
|
+
return unless actor.ancestors.include?(ServiceActor::Core)
|
|
71
|
+
|
|
72
|
+
actor = actor.new(result)
|
|
73
|
+
actor._call
|
|
70
74
|
|
|
71
75
|
(@played ||= []).unshift(actor)
|
|
72
76
|
end
|
|
77
|
+
|
|
78
|
+
def play_interactor(actor)
|
|
79
|
+
return unless actor.is_a?(Class)
|
|
80
|
+
return unless actor.ancestors.map(&:name).include?('Interactor')
|
|
81
|
+
|
|
82
|
+
result.merge!(actor.call(result).to_h)
|
|
83
|
+
end
|
|
73
84
|
end
|
|
74
85
|
end
|
|
75
86
|
end
|
data/lib/service_actor/result.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: service_actor
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.1.
|
|
4
|
+
version: 3.1.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sunny Ripert
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-01-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rspec
|
|
@@ -156,6 +156,7 @@ metadata:
|
|
|
156
156
|
homepage_uri: https://github.com/sunny/actor
|
|
157
157
|
source_code_uri: https://github.com/sunny/actor
|
|
158
158
|
changelog_uri: https://github.com/sunny/actor/blob/main/CHANGELOG.md
|
|
159
|
+
rubygems_mfa_required: 'true'
|
|
159
160
|
post_install_message:
|
|
160
161
|
rdoc_options: []
|
|
161
162
|
require_paths:
|
|
@@ -171,7 +172,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
171
172
|
- !ruby/object:Gem::Version
|
|
172
173
|
version: '0'
|
|
173
174
|
requirements: []
|
|
174
|
-
rubygems_version: 3.1.
|
|
175
|
+
rubygems_version: 3.1.6
|
|
175
176
|
signing_key:
|
|
176
177
|
specification_version: 4
|
|
177
178
|
summary: Service objects for your application logic
|