civil_service 2.1.0 → 2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7852028628b07b8e1cb66afa9b93551f7b8d1c617ba3161adf20d05355e53da4
4
- data.tar.gz: 414e35fa95fadd0b904c82699958279c029bc2047f7c21b46631beed0a80ae3f
3
+ metadata.gz: 4a4a50e4d4765b2e8805078eeca14e8e0adfba0bd5e04c855ff3aae3263d2542
4
+ data.tar.gz: 9bda59ba00a76044a5ba5989302e77ef8d6ece6eb68f0001e8d45f5a17c2bbb1
5
5
  SHA512:
6
- metadata.gz: 7752f150f11331751baf46f61c69cdf338196edc9ff5b4e86e42035c1d524c3d3bffa54d1c58a08f869b27ec05219cfe142c334a5582ed53ae4b8380e802fdd9
7
- data.tar.gz: 10c2096c1ff5e6b967969d00be432d72c6a3811dbd7bdc6ee7d4b04fbea4da52676cb0f5f1344fadb65e842f9b3b494cbe3c7ec1370c269d4f613d22dfe31888
6
+ metadata.gz: 227d0b3c5e2bff1e011ad42088b18308e6d46074a90acf8852585a22ec95ca51179be13692ed21ccbb53919e69324599496308101586b6afb7d3dff39b17d1d7
7
+ data.tar.gz: a8cd818e88f53583333832e6a9525e00d8b20a9898808068aae120dc02646ae8ff8e676ce944c18d13727c67c37f5e852be7bd2a8d49c7b944cdbaeb31828598
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ # Version 2.2.0 - September 26, 2019
2
+
3
+ * Services now have a new `#call_and_raise` method, which will return a result object on failure
4
+ but will raise exceptions that are thrown inside the service call (effectively, the behavior of
5
+ `#call` in CivilService 1.0.0).
6
+ * Added a new mixin called `CivilService::MultiResultService`, which allows creating services whose
7
+ results are composed of multiple results that are aggregated together.
8
+
1
9
  # Version 2.1.0 - September 25, 2019
2
10
 
3
11
  * `CivilService::Result#errors` now always returns an Errors object even if it hasn't been
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- civil_service (2.1.0)
4
+ civil_service (2.2.0)
5
5
  activemodel (>= 3.0.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -4,7 +4,7 @@
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/neinteractiveliterature/civil_service.
91
+ Bug reports and pull requests are welcome on GitHub at https://github.com/actblue/civil_service.
data/lib/civil_service.rb CHANGED
@@ -3,3 +3,4 @@ require "active_model"
3
3
  require "civil_service/result"
4
4
  require "civil_service/service_failure"
5
5
  require "civil_service/service"
6
+ require "civil_service/multi_result_service"
@@ -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
+ (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
@@ -25,6 +25,15 @@ class CivilService::Service
25
25
  end
26
26
  end
27
27
 
28
+ def call_and_raise
29
+ result = call
30
+ if result.exception
31
+ raise result.exception, result.exception.message, result.exception.backtrace
32
+ end
33
+
34
+ result
35
+ end
36
+
28
37
  def call!
29
38
  unless self.class.validate_manually
30
39
  raise CivilService::ServiceFailure.new(self, failure(errors)) unless valid?
@@ -1,3 +1,3 @@
1
1
  module CivilService
2
- VERSION = "2.1.0"
2
+ VERSION = "2.2.0"
3
3
  end
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.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nat Budin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-09-25 00:00:00.000000000 Z
11
+ date: 2019-09-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -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