service_pattern 0.0.2 → 0.0.7

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
- SHA1:
3
- metadata.gz: d6787a4f53bfdd57a07123e7eced76fdce0857cd
4
- data.tar.gz: 1dede4fdc6bfcd28b8fef48927f8d1362c0a0dfa
2
+ SHA256:
3
+ metadata.gz: 77863da179021d925441d0bf4a64fe8756ce925c45262523e7e34ff35e03956b
4
+ data.tar.gz: 815cac6f2393f6f92181a14fd311c565d63069e96c9aebc3827c315fa24d2832
5
5
  SHA512:
6
- metadata.gz: 1de0f2175621e1ab35333e41ce768bb0b44bc92468b0c5266faee84658bff910fa1fdceb766dcfe649b16a4711ced4c34b40569e9602c847d6706ac72f6b05f0
7
- data.tar.gz: 5332d4b8173004adee2ba1e6061e793cf3c7ee39cee66b2cac2df390218260c63dddbd5204903e545b7622d7061e4dd799768e26dafc7630773389133a28cc0b
6
+ metadata.gz: 370ba577ae9fc3a77746e518502c71d872e22ee49ddab016124c1c3105a48b8cc6667e22ea4f9369f4224b9de298c3ff04940031eb86aeb1e8d9f8890fcb0289
7
+ data.tar.gz: a80e81f4419b97fa4721a747a180729484264635d4feff4edb572d5e4dabda6a11d86928d1ba5fb1fcf11c9bd94734d82c9449bce4c8ee7d762af3c5e47de19c
data/README.md CHANGED
@@ -12,5 +12,73 @@ Add this line to your application's Gemfile:
12
12
  gem "service_pattern"
13
13
  ```
14
14
 
15
+ Create an application service that your other services will enherit from in "app/services/application_service":
16
+ ```ruby
17
+ class ApplicationService < ServicePattern::Service
18
+ end
19
+ ```
20
+
21
+ Create your first service in "app/services/users/activator_service":
22
+ ```ruby
23
+ class Users::ActivatorService < ApplicationService
24
+ def execute
25
+ User.all.find_each(&:activate!)
26
+ succeed!
27
+ end
28
+ end
29
+ ```
30
+
31
+ Then call it like this:
32
+ ```ruby
33
+ response = Users::ActivatorService.()
34
+
35
+ if response.success?
36
+ puts "Result: #{response.result}"
37
+ else
38
+ puts "Errors: #{response.errors.join(". ")}"
39
+ end
40
+ ```
41
+
42
+ Or like this:
43
+ ```ruby
44
+ response = Users::ActivatorService.execute()
45
+
46
+ if response.success?
47
+ puts "Result: #{response.result}"
48
+ else
49
+ puts "Errors: #{response.errors.join(". ")}"
50
+ end
51
+ ```
52
+
53
+ Or raise an error if it fails and return the result directly:
54
+ ```ruby
55
+ result = Users::ActivatorService.execute!
56
+
57
+ puts "Result: #{result}"
58
+ ```
59
+
60
+ ### Returning results
61
+
62
+ You can also return a result, which will automatically make the response successfull:
63
+ ```ruby
64
+ succeed!(message: "Hello world")
65
+ ```
66
+
67
+ You can then retrieve it like this:
68
+ ```ruby
69
+ response = Users::ActivatorService.()
70
+ puts "Result: #{response.result}"
71
+ ```
72
+
73
+ You can fail a service like this
74
+ ```ruby
75
+ fail! "Hello world"
76
+ ```
77
+
78
+ Or with multiple errors:
79
+ ```ruby
80
+ fail! ["Hello world", "Hello again"]
81
+ ```
82
+
15
83
  ## License
16
84
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -1,7 +1,8 @@
1
1
  module ServicePattern
2
2
  path = "#{File.dirname(__FILE__)}/service_pattern"
3
3
 
4
- autoload :CantExecuteError, "#{path}/cant_execute_error"
4
+ autoload :FailError, "#{path}/fail_error"
5
+ autoload :FailedError, "#{path}/failed_error"
5
6
  autoload :Response, "#{path}/response"
6
7
  autoload :Service, "#{path}/service"
7
8
  end
@@ -0,0 +1,8 @@
1
+ class ServicePattern::FailError
2
+ attr_reader :message, :type
3
+
4
+ def initialize(message:, type: nil)
5
+ @message = message
6
+ @type = type
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ class ServicePattern::FailedError < RuntimeError
2
+ attr_accessor :errors
3
+
4
+ def error_messages
5
+ @error_messages ||= @errors.map(&:message)
6
+ end
7
+
8
+ def error_types
9
+ @error_types ||= @errors.map(&:type)
10
+ end
11
+ end
@@ -1,19 +1,18 @@
1
1
  class ServicePattern::Response
2
2
  attr_reader :errors, :result
3
3
 
4
- def initialize(args)
5
- @errors = args[:errors] || []
6
- @result = args[:result]
4
+ def initialize(errors: [], result: nil)
5
+ @errors = errors
6
+ @result = result
7
+ @success = !errors || errors.empty?
8
+ end
9
+
10
+ def error_messages
11
+ @error_messages ||= @errors.map(&:message)
12
+ end
7
13
 
8
- if args.key?(:success)
9
- @success = args.fetch(:success)
10
- elsif args.key?(:errors) && @errors.any?
11
- @success = false
12
- elsif @result
13
- @success = true
14
- else
15
- raise "Couldn't figure out if it was a success"
16
- end
14
+ def error_types
15
+ @error_types ||= @errors.map(&:type).reject(&:blank?)
17
16
  end
18
17
 
19
18
  def success?
@@ -1,32 +1,68 @@
1
1
  class ServicePattern::Service
2
- def self.call(*args)
3
- service = new(*args)
2
+ # The same as execute but doesn't catch FailedError so they are passed on to the parent service call
3
+ def self.chain(*args, &blk)
4
+ service = new(*args, &blk)
4
5
 
5
- begin
6
- can_execute_response = service.can_execute?
6
+ can_execute_response = service.can_execute?
7
+ ServicePattern::Service.fail!(can_execute_response.errors) unless can_execute_response.success?
7
8
 
8
- puts "can_execute_response: #{can_execute_response.success?} (#{can_execute_response.errors})"
9
+ service.execute
10
+ end
9
11
 
10
- return can_execute_response unless can_execute_response.success?
11
- service.execute!
12
- rescue => e
13
- ServicePattern::Response.new(errors: ["#{e.class.name}: #{e.message}"], success: false)
14
- end
12
+ def self.call(*args, &blk)
13
+ execute(*args, &blk)
15
14
  end
16
15
 
17
- def self.execute!(*args)
18
- service = new(*args)
16
+ def self.execute(*args, &blk)
17
+ service = new(*args, &blk)
19
18
 
20
19
  can_execute_response = service.can_execute?
21
- raise ServicePattern::CantExecuteError, can_execute_response.errors.join(". ") unless can_execute_response.success?
22
- service.execute!
20
+ return can_execute_response unless can_execute_response.success?
21
+
22
+ service.execute
23
+ rescue ServicePattern::FailedError => e
24
+ ServicePattern::Response.new(errors: e.errors)
25
+ end
26
+
27
+ def self.execute!(*args, &blk)
28
+ service = new(*args, &blk)
29
+ can_execute_response = service.can_execute?
30
+ ServicePattern::Service.fail!(can_execute_response.errors) unless can_execute_response.success?
31
+ response = service.execute
32
+ ServicePattern::Service.fail!(response.errors) unless response.success?
33
+ response.result
34
+ end
35
+
36
+ def self.fail!(errors)
37
+ errors = [errors] unless errors.is_a?(Array)
38
+ errors = errors.map do |error|
39
+ error = ServicePattern::FailError.new(message: error) unless error.is_a?(ServicePattern::FailError)
40
+ error
41
+ end
42
+
43
+ error_messages = errors.map(&:message)
44
+
45
+ error = ServicePattern::FailedError.new(error_messages.join(". "))
46
+ error.errors = errors
47
+
48
+ raise error
23
49
  end
24
50
 
25
51
  def can_execute?
26
- ServicePattern::Response.new(success: true)
52
+ succeed!
53
+ end
54
+
55
+ def execute(*_args)
56
+ raise NoMethodError, "You should implement the `execute` method on your service"
57
+ end
58
+
59
+ def fail!(errors, type: nil)
60
+ errors = [ServicePattern::FailError.new(message: errors, type: type)] if type
61
+
62
+ ServicePattern::Service.fail!(errors)
27
63
  end
28
64
 
29
- def execute!(*_args)
30
- raise NoMethodError, "You should implement the `execute!` method on your service"
65
+ def succeed!(result = nil)
66
+ ServicePattern::Response.new(result: result)
31
67
  end
32
68
  end
@@ -1,3 +1,3 @@
1
1
  module ServicePattern
2
- VERSION = "0.0.2".freeze
2
+ VERSION = "0.0.7".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: service_pattern
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - kaspernj
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-19 00:00:00.000000000 Z
11
+ date: 2020-09-02 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: ServicePattern for Ruby on Rails.
14
14
  email:
@@ -21,7 +21,8 @@ files:
21
21
  - README.md
22
22
  - Rakefile
23
23
  - lib/service_pattern.rb
24
- - lib/service_pattern/cant_execute_error.rb
24
+ - lib/service_pattern/fail_error.rb
25
+ - lib/service_pattern/failed_error.rb
25
26
  - lib/service_pattern/response.rb
26
27
  - lib/service_pattern/service.rb
27
28
  - lib/service_pattern/version.rb
@@ -45,8 +46,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
45
46
  - !ruby/object:Gem::Version
46
47
  version: '0'
47
48
  requirements: []
48
- rubyforge_project:
49
- rubygems_version: 2.6.8
49
+ rubygems_version: 3.0.6
50
50
  signing_key:
51
51
  specification_version: 4
52
52
  summary: ServicePattern for Ruby on Rails.
@@ -1 +0,0 @@
1
- class ServicePattern::CantExecuteError < RuntimeError; end