service_pattern 0.0.4 → 1.0.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: eb37f2c1aa001cef4abdfe0937e15b82c52bb845d44c9527851bc6d770bfd44d
4
- data.tar.gz: 52344b2c5450cb137bcb743c4fe24bf543e5c22c8d61a831a063d5a4b5de7829
3
+ metadata.gz: cdb56345fc9435ba6661951aa8d3cc5176022c2767881b340b6551c94c8e4caa
4
+ data.tar.gz: f9fc3f3ae0262dfa6c0ff58505cce750070074bdf9cb8d52ed826695ec3eb46e
5
5
  SHA512:
6
- metadata.gz: 432e00eceea33e9f3335bcc00a5fc44f153ddbf925e11b853d3e6c698607bac1f090a6060eaa88875c5535d86863212409426b28a7ae5a1c66ad42991ceae1ca
7
- data.tar.gz: a072a0f461b12c9e09e7a9d2c80ee593015434797cb6da32ef7825f0ab1c834e6d77caf22cc36ad264f52950980931cef6b7a6de3930a4d53280b2ef563673aa
6
+ metadata.gz: 5466648e3d09f9add63cd3205a94f4f27e9d732a322e84eba8982f16d8d448d745669fcdbd38ddb04a5ac29663491129ef7ef315589b37c5a5e43fe118f94563
7
+ data.tar.gz: b1dfe83d17699a4eb998a7a85614e735979443c2baedd27d51d65549a2896e4377b65c150c6b0a55889d194d6d25c7212fe6ea90a8db31ab62f9a23393d31b4d
data/README.md CHANGED
@@ -23,7 +23,7 @@ Create your first service in "app/services/users/activator_service":
23
23
  class Users::ActivatorService < ApplicationService
24
24
  def execute
25
25
  User.all.find_each(&:activate!)
26
- ServicePattern::Response.new(success: true)
26
+ succeed!
27
27
  end
28
28
  end
29
29
  ```
@@ -33,17 +33,35 @@ Then call it like this:
33
33
  response = Users::ActivatorService.()
34
34
 
35
35
  if response.success?
36
- puts "Wee"
36
+ puts "Result: #{response.result}"
37
37
  else
38
- puts "Errors: #{result.errors.join(". ")}"
38
+ puts "Errors: #{response.errors.join(". ")}"
39
39
  end
40
40
  ```
41
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
+
42
60
  ### Returning results
43
61
 
44
62
  You can also return a result, which will automatically make the response successfull:
45
63
  ```ruby
46
- ServicePattern::Response.new(result: {message: "Hello world"})
64
+ succeed!(message: "Hello world")
47
65
  ```
48
66
 
49
67
  You can then retrieve it like this:
@@ -52,5 +70,15 @@ response = Users::ActivatorService.()
52
70
  puts "Result: #{response.result}"
53
71
  ```
54
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
+
55
83
  ## License
56
84
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -1,6 +1,7 @@
1
1
  module ServicePattern
2
2
  path = "#{File.dirname(__FILE__)}/service_pattern"
3
3
 
4
+ autoload :FailError, "#{path}/fail_error"
4
5
  autoload :FailedError, "#{path}/failed_error"
5
6
  autoload :Response, "#{path}/response"
6
7
  autoload :Service, "#{path}/service"
@@ -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
@@ -1 +1,11 @@
1
- class ServicePattern::FailedError < RuntimeError; end
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 = ServicePattern::Service.convert_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?
@@ -4,9 +4,9 @@ class ServicePattern::Service
4
4
  service = new(*args, &blk)
5
5
 
6
6
  can_execute_response = service.can_execute?
7
- raise ServicePattern::FailedError, can_execute_response.errors.join(". ") unless can_execute_response.success?
7
+ ServicePattern::Service.fail!(can_execute_response.errors) unless can_execute_response.success?
8
8
 
9
- service.execute
9
+ service.perform
10
10
  end
11
11
 
12
12
  def self.call(*args, &blk)
@@ -15,27 +15,60 @@ class ServicePattern::Service
15
15
 
16
16
  def self.execute(*args, &blk)
17
17
  service = new(*args, &blk)
18
+ service.execute
19
+ end
18
20
 
21
+ def self.execute!(*args, &blk)
22
+ service = new(*args, &blk)
19
23
  can_execute_response = service.can_execute?
20
- return can_execute_response unless can_execute_response.success?
24
+ ServicePattern::Service.fail!(can_execute_response.errors) unless can_execute_response.success?
25
+ response = service.perform
26
+ ServicePattern::Service.fail!(response.errors) unless response.success?
27
+ response.result
28
+ end
21
29
 
22
- service.execute
23
- rescue ServicePattern::FailedError => e
24
- ServicePattern::Response.new(errors: [e.message])
30
+ def self.convert_errors(errors)
31
+ errors = [errors] unless errors.is_a?(Array)
32
+ errors.map do |error|
33
+ error = ServicePattern::FailError.new(message: error) unless error.is_a?(ServicePattern::FailError)
34
+ error
35
+ end
25
36
  end
26
37
 
27
- def self.execute!(*args, &blk)
28
- response = execute(*args, &blk)
29
- raise ServicePattern::FailedError, response.errors.join(". ") unless response.success?
38
+ def self.fail!(errors)
39
+ errors = convert_errors(errors)
40
+ error_messages = errors.map(&:message)
30
41
 
31
- response.result
42
+ error = ServicePattern::FailedError.new(error_messages.join(". "))
43
+ error.errors = errors
44
+
45
+ raise error
32
46
  end
33
47
 
34
48
  def can_execute?
35
- ServicePattern::Response.new(success: true)
49
+ succeed!
50
+ end
51
+
52
+ def execute
53
+ can_execute_response = can_execute?
54
+ return can_execute_response unless can_execute_response.success?
55
+
56
+ perform
57
+ rescue ServicePattern::FailedError => e
58
+ ServicePattern::Response.new(errors: e.errors)
59
+ end
60
+
61
+ def perform(*_args)
62
+ raise NoMethodError, "You should implement the `perform` method on your service"
63
+ end
64
+
65
+ def fail!(errors, type: nil)
66
+ errors = [ServicePattern::FailError.new(message: errors, type: type)] if type
67
+
68
+ ServicePattern::Service.fail!(errors)
36
69
  end
37
70
 
38
- def execute(*_args)
39
- raise NoMethodError, "You should implement the `execute!` method on your service"
71
+ def succeed!(result = nil)
72
+ ServicePattern::Response.new(result: result)
40
73
  end
41
74
  end
@@ -1,3 +1,3 @@
1
1
  module ServicePattern
2
- VERSION = "0.0.4".freeze
2
+ VERSION = "1.0.0".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.4
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - kaspernj
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-19 00:00:00.000000000 Z
11
+ date: 2021-05-26 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: ServicePattern for Ruby on Rails.
14
14
  email:
@@ -21,6 +21,7 @@ files:
21
21
  - README.md
22
22
  - Rakefile
23
23
  - lib/service_pattern.rb
24
+ - lib/service_pattern/fail_error.rb
24
25
  - lib/service_pattern/failed_error.rb
25
26
  - lib/service_pattern/response.rb
26
27
  - lib/service_pattern/service.rb
@@ -38,7 +39,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
38
39
  requirements:
39
40
  - - ">="
40
41
  - !ruby/object:Gem::Version
41
- version: '0'
42
+ version: 2.5.0
42
43
  required_rubygems_version: !ruby/object:Gem::Requirement
43
44
  requirements:
44
45
  - - ">="