servactory 1.2.0 → 1.3.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: 9ef221cf056da7376cec0a04e0dd92ddba328f34163fe050d74e3f0158eb1e17
4
- data.tar.gz: 2bc1b62867fb2e6c09692bfd76c315bbf739202b445fc99e46511b6dd3437c6f
3
+ metadata.gz: e9766f87f647b0873a6671d88811141a77b571fb15ac5ee6b10b78e2e5696ca6
4
+ data.tar.gz: c36ee73abad2d9241f6b48190cbf3351fe8c9c40bc7cb9bdfdfb09c04e5d05f8
5
5
  SHA512:
6
- metadata.gz: 126ca96b81dcbea82334b216f9b911c33282aca4c66c26d511655339cd56184ce6fac7475420184f6fcd4681d34afe210f8ebffe18e0894c635c6bcbdc045754
7
- data.tar.gz: 22675c25495d5e2b3edfda926c5392985294c78c03e0e2d6f8930b8a8d5a7618dc94dd7cec413fba5b6ce234d23bbeea44c68cf58fc95d0e223c73c437721b43
6
+ metadata.gz: 11b27258c9a302cb989eed03fe4f1325c03855f58fd3a79b6cad7a3846fa8e9395f780fe0d9a2dd30c9b044d4e98df4677857c93c275f9bfe8780d6ebefe5d5e
7
+ data.tar.gz: 57800e68b8c8bece089513dcf0b0ff8da6ab2efb33a4d4a694b11995dae51b7dd0496b1b0f4b6c0ba403db5c6037432e43371d68bea5b56bb05844d98fb36e8e
data/README.md CHANGED
@@ -81,36 +81,105 @@ class SendService < ApplicationService::Base
81
81
  end
82
82
  ```
83
83
 
84
- ### Inputs
84
+ ### Input attributes
85
+
86
+ #### Isolated usage
87
+
88
+ With this approach, all input attributes are available only from `inputs`.
85
89
 
86
90
  ```ruby
87
- class SendService < ApplicationService::Base
91
+ class UserService::Accept < ApplicationService::Base
88
92
  input :user, type: User
89
93
 
90
- stage { make :something }
94
+ stage { make :accept! }
91
95
 
92
96
  private
93
97
 
94
- def something
95
- # ...
98
+ def accept!
99
+ inputs.user.accept!
96
100
  end
97
101
  end
98
102
  ```
99
103
 
100
- ### Outputs
104
+ #### As an internal argument
105
+
106
+ With this approach, all input attributes are available from `inputs` as well as directly from the context.
101
107
 
102
108
  ```ruby
103
- class SendService < ApplicationService::Base
109
+ class UserService::Accept < ApplicationService::Base
110
+ input :user, type: User, internal: true
111
+
112
+ stage { make :accept! }
113
+
114
+ private
115
+
116
+ def accept!
117
+ user.accept!
118
+ end
119
+ end
120
+ ```
121
+
122
+ ### Output attributes
123
+
124
+ ```ruby
125
+ class NotificationService::Create < ApplicationService::Base
104
126
  input :user, type: User
105
127
 
106
128
  output :notification, type: Notification
107
129
 
108
- stage { make :something }
130
+ stage { make :create_notification! }
109
131
 
110
132
  private
111
133
 
112
- def something
113
- self.notification = Notification.create!
134
+ def create_notification!
135
+ self.notification = Notification.create!(user: inputs.user)
136
+ end
137
+ end
138
+ ```
139
+
140
+ ### Internal attributes
141
+
142
+ ```ruby
143
+ class NotificationService::Create < ApplicationService::Base
144
+ input :user, type: User
145
+
146
+ internal :inviter, type: User
147
+
148
+ output :notification, type: Notification
149
+
150
+ stage do
151
+ make :assign_inviter
152
+ make :create_notification!
153
+ end
154
+
155
+ private
156
+
157
+ def assign_inviter
158
+ self.inviter = user.inviter
159
+ end
160
+
161
+ def create_notification!
162
+ self.notification = Notification.create!(user: inputs.user, inviter:)
114
163
  end
115
164
  end
116
165
  ```
166
+
167
+ ### Result
168
+
169
+ All services have the result of their work. For example, in case of success this call:
170
+
171
+ ```ruby
172
+ service_result = NotificationService::Create.call!(user: User.first)
173
+ ```
174
+
175
+ Will return this:
176
+
177
+ ```ruby
178
+ #<Servactory::Result:0x0000000112c00748 @notification=...>
179
+ ```
180
+
181
+ And then you can work with this result, for example, in this way:
182
+
183
+ ```ruby
184
+ Notification::SendJob.perform_later(service_result.notification.id)
185
+ ```
@@ -32,7 +32,7 @@ module Servactory
32
32
  @check_options = check_options
33
33
  end
34
34
 
35
- def check
35
+ def check # rubocop:disable Metrics/MethodLength
36
36
  @check_options.each do |code, options|
37
37
  message = call_or_fetch_message_from(code, options)
38
38
 
@@ -6,7 +6,15 @@ module Servactory
6
6
  class Type < Base
7
7
  DEFAULT_MESSAGE = lambda do |service_class_name:, input:, expected_type:, given_type:|
8
8
  if input.array?
9
- "[#{service_class_name}] Wrong type in input array `#{input.name}`, expected `#{expected_type}`"
9
+ array_message = input.array[:message]
10
+
11
+ if array_message.is_a?(Proc)
12
+ array_message.call(input: input, expected_type: expected_type)
13
+ elsif array_message.is_a?(String) && array_message.present?
14
+ array_message
15
+ else
16
+ "[#{service_class_name}] Wrong type in input array `#{input.name}`, expected `#{expected_type}`"
17
+ end
10
18
  else
11
19
  "[#{service_class_name}] Wrong type of input `#{input.name}`, " \
12
20
  "expected `#{expected_type}`, " \
@@ -3,6 +3,8 @@
3
3
  module Servactory
4
4
  module InputArguments
5
5
  class InputArgument
6
+ ARRAY_DEFAULT_VALUE = ->(is: false, message: nil) { { is: is, message: message } }
7
+
6
8
  attr_reader :name,
7
9
  :types,
8
10
  :inclusion,
@@ -18,7 +20,7 @@ module Servactory
18
20
 
19
21
  @inclusion = options.fetch(:inclusion, nil)
20
22
  @must = options.fetch(:must, nil)
21
- @array = options.fetch(:array, false)
23
+ @array = prepare_advanced_for(options.fetch(:array, ARRAY_DEFAULT_VALUE.call))
22
24
  @required = options.fetch(:required, true)
23
25
  @internal = options.fetch(:internal, false)
24
26
  @default = options.fetch(:default, nil)
@@ -35,6 +37,17 @@ module Servactory
35
37
  }
36
38
  end
37
39
 
40
+ def prepare_advanced_for(value)
41
+ if value.is_a?(Hash)
42
+ ARRAY_DEFAULT_VALUE.call(
43
+ is: value.fetch(:is, false),
44
+ message: value.fetch(:message, nil)
45
+ )
46
+ else
47
+ ARRAY_DEFAULT_VALUE.call(is: value)
48
+ end
49
+ end
50
+
38
51
  def conflict_code
39
52
  return :required_vs_default if required? && default_value_present?
40
53
  return :array_vs_array if array? && types.include?(Array)
@@ -52,7 +65,7 @@ module Servactory
52
65
  end
53
66
 
54
67
  def array?
55
- Servactory::Utils.boolean?(array)
68
+ Servactory::Utils.boolean?(array[:is])
56
69
  end
57
70
 
58
71
  def required?
@@ -3,7 +3,7 @@
3
3
  module Servactory
4
4
  module VERSION
5
5
  MAJOR = 1
6
- MINOR = 2
6
+ MINOR = 3
7
7
  PATCH = 0
8
8
 
9
9
  STRING = [MAJOR, MINOR, PATCH].join(".")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: servactory
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anton Sokolov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-05 00:00:00.000000000 Z
11
+ date: 2023-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zeitwerk