civil_service 2.1.0 → 2.4.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/CHANGELOG.md +30 -5
- data/Gemfile.lock +13 -14
- data/README.md +4 -3
- data/civil_service.gemspec +1 -1
- data/lib/civil_service/multi_result_service.rb +44 -0
- data/lib/civil_service/service.rb +14 -5
- data/lib/civil_service/version.rb +1 -1
- data/lib/civil_service.rb +1 -0
- metadata +9 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3cc309b95109e1703e10facefa160b6b3ec0d2c9cdeecc55c4d7fcca4fd3b788
|
4
|
+
data.tar.gz: bd935e564c4170b464e0fc5a577d885201c4a506f57bd5dd67ca69ceb5f5de5a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10fbcc6182d07401c5e13580246511f9b8d9de9724bf049e21e0b343dee7b147dd2447ad1b58660488366dd892e05cfd5a2dba30dfeb2bf02d7d526117f09316
|
7
|
+
data.tar.gz: cb07f3d6487e639cac8c0645dc2b316a0ef017986e7d3bea0e0eaef66e66f37241b34d08989f2c558e737a549afba2e8d8c0dd49ca9cdc642c7af9c0d7914578
|
data/CHANGELOG.md
CHANGED
@@ -1,12 +1,36 @@
|
|
1
|
+
# Version 2.4.0 - January 15, 2021
|
2
|
+
|
3
|
+
- `#call`, `#call_and_raise`, and `#call!` now accept an optional keyword parameter called `validate`. This will
|
4
|
+
skip validations if passed `false`. (`true` is the default value.)
|
5
|
+
- `#call!` now takes advantage of the `validate:` parameter internally to avoid running validations twice.
|
6
|
+
|
7
|
+
# Version 2.3.0 - April 3, 2020
|
8
|
+
|
9
|
+
- `#call!` now raises the underlying exception if the service threw an exception,
|
10
|
+
rather than hiding it inside a `CivilService::ServiceFailure`.
|
11
|
+
|
12
|
+
# Version 2.2.1 - October 4, 2019
|
13
|
+
|
14
|
+
- `CivilService::MultiResultService::MultiResult#exception` now checks the underlying exception on
|
15
|
+
the root result object, in case the service threw an exception.
|
16
|
+
|
17
|
+
# Version 2.2.0 - September 26, 2019
|
18
|
+
|
19
|
+
- Services now have a new `#call_and_raise` method, which will return a result object on failure
|
20
|
+
but will raise exceptions that are thrown inside the service call (effectively, the behavior of
|
21
|
+
`#call` in CivilService 1.0.0).
|
22
|
+
- Added a new mixin called `CivilService::MultiResultService`, which allows creating services whose
|
23
|
+
results are composed of multiple results that are aggregated together.
|
24
|
+
|
1
25
|
# Version 2.1.0 - September 25, 2019
|
2
26
|
|
3
|
-
|
27
|
+
- `CivilService::Result#errors` now always returns an Errors object even if it hasn't been
|
4
28
|
explicitly set.
|
5
29
|
|
6
30
|
# Version 2.0.0 - June 26, 2019
|
7
31
|
|
8
|
-
|
9
|
-
raised inside the service.
|
32
|
+
- BREAKING CHANGE: The behavior of `CivilService::Service#call` has changed when exceptions are
|
33
|
+
raised inside the service. The `call` method will now catch the exception and return a failing
|
10
34
|
result object, with the exception message as an error on `:base`.
|
11
35
|
|
12
36
|
The behavior of `call!` has not changed: a failing result will be raised as a
|
@@ -17,8 +41,9 @@
|
|
17
41
|
will (almost) never raise an exception, whereas `call!` can raise an exception.
|
18
42
|
|
19
43
|
The exception to this rule (pun intended, always intend your puns) is that `call` will not catch
|
20
|
-
exceptions that don't inherit from `StandardError`, such as `SystemExit`.
|
44
|
+
exceptions that don't inherit from `StandardError`, such as `SystemExit`. See
|
21
45
|
[Honeybadger's explanation](https://www.honeybadger.io/blog/a-beginner-s-guide-to-exceptions-in-ruby/)
|
22
46
|
of why this is a good idea.
|
23
|
-
|
47
|
+
|
48
|
+
- `CivilService::Result` now has an additional attribute called `exception`, which can be used to
|
24
49
|
retrieve an exception thrown inside a `call` method.
|
data/Gemfile.lock
CHANGED
@@ -1,27 +1,26 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
civil_service (2.
|
4
|
+
civil_service (2.4.0)
|
5
5
|
activemodel (>= 3.0.0)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
activemodel (
|
11
|
-
activesupport (=
|
12
|
-
activesupport (
|
10
|
+
activemodel (7.0.0)
|
11
|
+
activesupport (= 7.0.0)
|
12
|
+
activesupport (7.0.0)
|
13
13
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
14
|
-
i18n (>=
|
15
|
-
minitest (
|
16
|
-
tzinfo (~>
|
17
|
-
concurrent-ruby (1.1.
|
18
|
-
i18n (1.
|
14
|
+
i18n (>= 1.6, < 2)
|
15
|
+
minitest (>= 5.1)
|
16
|
+
tzinfo (~> 2.0)
|
17
|
+
concurrent-ruby (1.1.9)
|
18
|
+
i18n (1.8.11)
|
19
19
|
concurrent-ruby (~> 1.0)
|
20
20
|
minitest (5.11.3)
|
21
|
-
rake (
|
22
|
-
|
23
|
-
|
24
|
-
thread_safe (~> 0.1)
|
21
|
+
rake (13.0.1)
|
22
|
+
tzinfo (2.0.4)
|
23
|
+
concurrent-ruby (~> 1.0)
|
25
24
|
|
26
25
|
PLATFORMS
|
27
26
|
ruby
|
@@ -30,7 +29,7 @@ DEPENDENCIES
|
|
30
29
|
bundler (~> 1.16)
|
31
30
|
civil_service!
|
32
31
|
minitest (~> 5.0)
|
33
|
-
rake (~>
|
32
|
+
rake (~> 13.0)
|
34
33
|
|
35
34
|
BUNDLED WITH
|
36
35
|
1.17.2
|
data/README.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# CivilService
|
2
2
|
|
3
|
-
[](https://travis-ci.org/actblue/civil_service)
|
4
4
|
|
5
5
|
CivilService is a tiny framework for [service objects in Rails apps](https://hackernoon.com/service-objects-in-ruby-on-rails-and-you-79ca8a1c946e). With CivilService, you can use ActiveModel validations to do pre-flight checks before the service runs, and create your own result object classes to capture the results of complex operations.
|
6
6
|
|
7
|
-
CivilService was extracted from [Intercode](https://github.com/neinteractiveliterature/intercode), a web app for convention organizers and participants.
|
7
|
+
CivilService was extracted from [Intercode](https://github.com/neinteractiveliterature/intercode), a web app for convention organizers and participants. It is now maintained by ActBlue.
|
8
8
|
|
9
9
|
## Installation
|
10
10
|
|
@@ -30,6 +30,7 @@ CivilService::Service is really a pretty tiny class. It does, however, have som
|
|
30
30
|
* What's the difference between `#errors` and `#exception`? `#errors` is an instance of `ActiveModel::Errors`, whereas `#exception` is an instance of an exception class (it's only present if an exception was raised inside the service call). If an exception is raised, the service result will respond true to `#failure?`, false to `#success?`, and the exception's message will be added to `#errors`, so most of the time you can ignore `#exception` - but it's there in case you need to dig into the details.
|
31
31
|
* Services include `ActiveModel::Validations` so they can easily do pre-flight checks. That means you can call `my_service.valid?` and `my_service.errors` just like you can for a model, and it also means that the service will fail if it's not valid.
|
32
32
|
* In addition to `#call`, which always returns a result object, services have a `#call!` method, which will raise a `CivilService::ServiceFailure` exception if the service fails, or pass through an exception if one is raised inside the service call. This might be easier in some workflows; for example, it will cause a rollback if used inside an ActiveRecord transaction block.
|
33
|
+
* Finally, there's a third variant: `#call_and_raise`, which will re-raise any exceptions that occurred during the service execution, but will return a regular result object on failure.
|
33
34
|
|
34
35
|
## Basic example
|
35
36
|
|
@@ -87,4 +88,4 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
87
88
|
|
88
89
|
## Contributing
|
89
90
|
|
90
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
91
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/actblue/civil_service.
|
data/civil_service.gemspec
CHANGED
@@ -23,6 +23,6 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_dependency "activemodel", ">= 3.0.0"
|
24
24
|
|
25
25
|
spec.add_development_dependency "bundler", "~> 1.16"
|
26
|
-
spec.add_development_dependency "rake", "~>
|
26
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
27
27
|
spec.add_development_dependency "minitest", "~> 5.0"
|
28
28
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module CivilService::MultiResultService
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
class MultiResult < CivilService::Result
|
5
|
+
attr_accessor :results
|
6
|
+
|
7
|
+
def success?
|
8
|
+
(results || []).compact.all?(&:success)
|
9
|
+
end
|
10
|
+
|
11
|
+
def errors
|
12
|
+
errors = ActiveModel::Errors.new(self)
|
13
|
+
(results || []).compact.each do |result|
|
14
|
+
next if result.success?
|
15
|
+
result.errors.each do |attribute, error|
|
16
|
+
errors.add(attribute, error)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
errors
|
20
|
+
end
|
21
|
+
|
22
|
+
def exception
|
23
|
+
super || (results || []).compact.map(&:exception).compact.first
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def multi_result(results)
|
28
|
+
self.class.result_class.new(results: results)
|
29
|
+
end
|
30
|
+
|
31
|
+
class_methods do
|
32
|
+
def result_class=(result_class)
|
33
|
+
unless result_class <= CivilService::MultiResultService::MultiResult
|
34
|
+
raise 'In a MultiResultService, result_class must be a MultiResult'
|
35
|
+
end
|
36
|
+
|
37
|
+
@result_class = result_class
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
included do
|
42
|
+
self.result_class = CivilService::MultiResultService::MultiResult
|
43
|
+
end
|
44
|
+
end
|
@@ -12,8 +12,8 @@ class CivilService::Service
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
def call
|
16
|
-
|
15
|
+
def call(validate: true)
|
16
|
+
if validate && !self.class.validate_manually
|
17
17
|
return failure(errors) unless valid?
|
18
18
|
end
|
19
19
|
|
@@ -25,12 +25,21 @@ class CivilService::Service
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
29
|
-
|
28
|
+
def call_and_raise(validate: true)
|
29
|
+
result = call(validate: validate)
|
30
|
+
if result.exception
|
31
|
+
raise result.exception, result.exception.message, result.exception.backtrace
|
32
|
+
end
|
33
|
+
|
34
|
+
result
|
35
|
+
end
|
36
|
+
|
37
|
+
def call!(validate: true)
|
38
|
+
if validate && !self.class.validate_manually
|
30
39
|
raise CivilService::ServiceFailure.new(self, failure(errors)) unless valid?
|
31
40
|
end
|
32
41
|
|
33
|
-
result =
|
42
|
+
result = call_and_raise(validate: false) # we already just did the validation step if needed
|
34
43
|
raise CivilService::ServiceFailure.new(self, result) if result.failure?
|
35
44
|
result
|
36
45
|
end
|
data/lib/civil_service.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: civil_service
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nat Budin
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '13.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '13.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: minitest
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -88,6 +88,7 @@ files:
|
|
88
88
|
- bin/setup
|
89
89
|
- civil_service.gemspec
|
90
90
|
- lib/civil_service.rb
|
91
|
+
- lib/civil_service/multi_result_service.rb
|
91
92
|
- lib/civil_service/result.rb
|
92
93
|
- lib/civil_service/service.rb
|
93
94
|
- lib/civil_service/service_failure.rb
|
@@ -95,7 +96,7 @@ files:
|
|
95
96
|
homepage: https://github.com/neinteractiveliterature/civil_service
|
96
97
|
licenses: []
|
97
98
|
metadata: {}
|
98
|
-
post_install_message:
|
99
|
+
post_install_message:
|
99
100
|
rdoc_options: []
|
100
101
|
require_paths:
|
101
102
|
- lib
|
@@ -110,8 +111,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
111
|
- !ruby/object:Gem::Version
|
111
112
|
version: '0'
|
112
113
|
requirements: []
|
113
|
-
rubygems_version: 3.
|
114
|
-
signing_key:
|
114
|
+
rubygems_version: 3.1.6
|
115
|
+
signing_key:
|
115
116
|
specification_version: 4
|
116
117
|
summary: A tiny service object framework for Rails apps
|
117
118
|
test_files: []
|