hexx 6.0.3 → 7.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 +4 -4
- data/.rubocop.yml +3 -0
- data/README.rdoc +63 -48
- data/lib/hexx.rb +1 -0
- data/lib/hexx/coercible.rb +2 -2
- data/lib/hexx/configurable.rb +1 -1
- data/lib/hexx/{helpers → creators}/base.rb +11 -15
- data/lib/hexx/{helpers → creators}/coercion.rb +8 -8
- data/lib/hexx/{helpers → creators}/dependency.rb +8 -8
- data/lib/hexx/{helpers → creators}/module_dependency.rb +2 -2
- data/lib/hexx/{helpers → creators}/parameter.rb +1 -1
- data/lib/hexx/dependable.rb +1 -1
- data/lib/hexx/helpers/exceptions.rb +53 -0
- data/lib/hexx/helpers/messages.rb +28 -0
- data/lib/hexx/helpers/parameters.rb +47 -0
- data/lib/hexx/helpers/validations.rb +21 -0
- data/lib/hexx/message.rb +79 -0
- data/lib/hexx/null.rb +0 -4
- data/lib/hexx/service.rb +259 -208
- data/lib/hexx/service_invalid.rb +73 -0
- data/lib/hexx/version.rb +1 -1
- data/spec/hexx/helpers/exceptions_spec.rb +96 -0
- data/spec/hexx/helpers/messages_spec.rb +56 -0
- data/spec/hexx/helpers/parameters_spec.rb +96 -0
- data/spec/hexx/helpers/validations_spec.rb +32 -0
- data/spec/hexx/message_spec.rb +83 -0
- data/spec/hexx/service_invalid_spec.rb +46 -0
- data/spec/hexx/service_spec.rb +41 -242
- data/spec/spec_helper.rb +1 -1
- data/spec/{initializers → support/initializers}/focus.rb +0 -0
- data/spec/{initializers → support/initializers}/garbage_collection.rb +0 -0
- data/spec/{initializers → support/initializers}/i18n.rb +0 -0
- data/spec/{initializers → support/initializers}/random_order.rb +0 -0
- data/spec/{initializers → support/initializers}/rspec.rb +0 -0
- data/spec/support/matchers/methods.rb +11 -0
- metadata +37 -23
- data/lib/hexx/service/invalid.rb +0 -76
- data/lib/hexx/service/message.rb +0 -81
- data/spec/hexx/service/invalid_spec.rb +0 -52
- data/spec/hexx/service/message_spec.rb +0 -85
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Hexx
|
4
|
+
module Helpers
|
5
|
+
|
6
|
+
# @api hide
|
7
|
+
# The module provides helper methods to add and return service messages.
|
8
|
+
module Messages
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
def t(text, options = {})
|
12
|
+
return text unless text.is_a? Symbol
|
13
|
+
scope = %w(activemodel messages models) << self.class.name.underscore
|
14
|
+
I18n.t text, options.merge(scope: scope)
|
15
|
+
end
|
16
|
+
|
17
|
+
def messages
|
18
|
+
@messages ||= []
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_writer :messages
|
22
|
+
|
23
|
+
def add_message(type, text, options = {})
|
24
|
+
messages << Hexx::Message.new(type: type, text: t(text, options))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Hexx
|
4
|
+
|
5
|
+
# @api hide
|
6
|
+
# The module contains classes that defines helper methods for the service.
|
7
|
+
#
|
8
|
+
# Basically those methods are private inside the service. In the helper
|
9
|
+
# they are public, allowing them to be testable as a part of the gem's API.
|
10
|
+
module Helpers
|
11
|
+
|
12
|
+
# @api hide
|
13
|
+
# The module declares helper methods for managing service object's params.
|
14
|
+
module Parameters
|
15
|
+
extend ActiveSupport::Concern
|
16
|
+
|
17
|
+
# @api hide
|
18
|
+
# Class helper methods
|
19
|
+
module ClassMethods
|
20
|
+
|
21
|
+
def allow_params(*keys)
|
22
|
+
@params = keys.flatten.map(&:to_s)
|
23
|
+
fail ArgumentError if @params == []
|
24
|
+
params.each { |name| Creators::Parameter.add self, name }
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def params
|
30
|
+
@params ||= []
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
attr_reader :params
|
35
|
+
|
36
|
+
def initialize(params = {})
|
37
|
+
@params = params.stringify_keys.slice(*class_params)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def class_params
|
43
|
+
@class_params ||= self.class.send :params
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative "messages"
|
3
|
+
|
4
|
+
module Hexx
|
5
|
+
module Helpers
|
6
|
+
|
7
|
+
# @api hide
|
8
|
+
# The module declares instance helper methods to provide validations
|
9
|
+
module Validations
|
10
|
+
extend ActiveSupport::Concern
|
11
|
+
|
12
|
+
def validate!
|
13
|
+
fail Hexx::ServiceInvalid.new(self) unless valid?
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.included(klass)
|
17
|
+
klass.send :include, ActiveModel::Validations
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/hexx/message.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
module Hexx
|
2
|
+
|
3
|
+
# A message to be returned by services.
|
4
|
+
class Message
|
5
|
+
include Comparable
|
6
|
+
|
7
|
+
# @!attribute [r] type
|
8
|
+
# The type of the message
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# message = Message.new type: :error, text: "message"
|
12
|
+
# message.type = "error"
|
13
|
+
#
|
14
|
+
# @return [String] The type of the message.
|
15
|
+
attr_reader :type
|
16
|
+
|
17
|
+
# @!attribute [r] text
|
18
|
+
# The text of the message
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# message = Message.new type: :error, text: "message"
|
22
|
+
# message.text = "message"
|
23
|
+
#
|
24
|
+
# @return [String] The text of the message.
|
25
|
+
attr_reader :text
|
26
|
+
|
27
|
+
# @!scope class
|
28
|
+
# @!method new(options)
|
29
|
+
# Constructs the message with type and text.
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# Message.new type: "success", text: "Object created."
|
33
|
+
#
|
34
|
+
# @param [Hash] options The list of the message attributes.
|
35
|
+
# @option options [String, Symbol] :type The type of the message.
|
36
|
+
# @option options [String, Symbol] :text The text of the message.
|
37
|
+
# @return [Hexx::Message] The message.
|
38
|
+
|
39
|
+
# @api hide
|
40
|
+
def initialize(type:, text:)
|
41
|
+
@type, @text = type.to_s, text.to_s
|
42
|
+
end
|
43
|
+
|
44
|
+
# Distinguishes two messages by type and text.
|
45
|
+
#
|
46
|
+
# @example
|
47
|
+
# a = Message.new(type: "a", text: "a")
|
48
|
+
# b = Message.new(type: "a", text: "a")
|
49
|
+
# c = Message.new(type: "b", text: "a")
|
50
|
+
# d = Message.new(type: "a", text: "b")
|
51
|
+
#
|
52
|
+
# a == b # => true
|
53
|
+
# a == c # => false
|
54
|
+
# a == d # => false
|
55
|
+
#
|
56
|
+
# @param [Object] other The object for the comparison.
|
57
|
+
# @return [Boolean] The result of the comparison.
|
58
|
+
def ==(other)
|
59
|
+
return false unless other.is_a? self.class
|
60
|
+
[type, text] == [other.type, other.text]
|
61
|
+
end
|
62
|
+
|
63
|
+
# Compares messages by type and text.
|
64
|
+
#
|
65
|
+
# @example
|
66
|
+
# ab = Message.new(type: "a", text: "b")
|
67
|
+
# ba = Message.new(type: "b", text: "a")
|
68
|
+
# ab < ba # => true
|
69
|
+
#
|
70
|
+
# @param [Object] other The object for the comparison.
|
71
|
+
# @return [-1, 0, 1] The result of the comparison if the argument is
|
72
|
+
# comparable with the message.
|
73
|
+
# @return [nil] if the result is incomparable with the message.
|
74
|
+
def <=>(other)
|
75
|
+
fail ArgumentError unless other.is_a? self.class
|
76
|
+
[type, text] <=> [other.type, other.text]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/hexx/null.rb
CHANGED
@@ -3,10 +3,6 @@
|
|
3
3
|
module Hexx
|
4
4
|
|
5
5
|
# The Null object class.
|
6
|
-
# @see http://robots.thoughtbot.com/rails-refactoring-example-introduce-null-object
|
7
|
-
# The intro to null object pattern from Dan Croak.
|
8
|
-
# @see http://devblog.avdi.org/2011/05/30/null-objects-and-falsiness/
|
9
|
-
# The post of Avdi Grimm on null object falsiness problem.
|
10
6
|
#
|
11
7
|
# Except for some special cases (see examples below) calling any method
|
12
8
|
# returns the +Null+ itself.
|
data/lib/hexx/service.rb
CHANGED
@@ -20,186 +20,306 @@ module Hexx
|
|
20
20
|
# service.run
|
21
21
|
# # => This will call the listener's method #on_found(item).
|
22
22
|
class Service
|
23
|
-
extend Dependable
|
24
|
-
include Wisper::Publisher
|
25
|
-
include ActiveModel::Validations
|
26
|
-
|
27
|
-
# Class helper methods
|
28
|
-
class << self
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
# @api hide
|
33
|
-
# Returns the list of allowed parameters for service objects.
|
34
|
-
#
|
35
|
-
# The parameters are added to the list by the {.allow_params} private
|
36
|
-
# helper method.
|
37
|
-
#
|
38
|
-
# @example
|
39
|
-
# class Service < Hexx::Service
|
40
|
-
# allow_params :name
|
41
|
-
# end
|
42
|
-
#
|
43
|
-
# Service.params # => "name"
|
44
|
-
#
|
45
|
-
# @return [Array<String>] Whitelist of parameters.
|
46
|
-
def params
|
47
|
-
@params ||= []
|
48
|
-
end
|
49
|
-
|
50
|
-
# Sets a list of allowed parameters for the class constructor and
|
51
|
-
# defines the corresponding instance attributes.
|
52
|
-
#
|
53
|
-
# @example (see Hexx::Service::Parameters.params)
|
54
|
-
# @param [Array<Symbol, String>] keys The list of allowed parameters.
|
55
|
-
def allow_params(*keys)
|
56
|
-
@params = keys.flatten.map(&:to_s)
|
57
|
-
fail ArgumentError if @params == []
|
58
|
-
params.each { |name| Helpers::Parameter.add self, name }
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
# @!scope class
|
63
|
-
# @!method validates(attribute, options)
|
64
|
-
# Adds a standard validation for the attribute.
|
65
|
-
# @param [Symbol, String] attribute The name of the attribute to validate.
|
66
|
-
# @param [Hash] options The list of validation options.
|
67
|
-
# @see ActiveModel validations {APIdocs}[
|
68
|
-
# http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validates]
|
69
23
|
|
70
|
-
|
71
|
-
# @!method validate(method, options)
|
72
|
-
# Adds a custom validation (calls given method).
|
73
|
-
# @param [Symbol, String] method The name of the validation method.
|
74
|
-
# @param [Hash] options The list of validation options.
|
75
|
-
# @see ActiveModel validations {APIdocs}[
|
76
|
-
# http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validate]
|
24
|
+
include Wisper::Publisher
|
77
25
|
|
78
|
-
# @!
|
79
|
-
# @!
|
80
|
-
#
|
26
|
+
# @!method subscribe(listener, options = {})
|
27
|
+
# @!visibility public
|
28
|
+
# Subscribes the listener to service object's notifications.
|
81
29
|
#
|
82
30
|
# @example (see Hexx::Service)
|
83
|
-
# @param [
|
84
|
-
#
|
85
|
-
# @
|
31
|
+
# @param [Object] listener The object that should receive notifications from
|
32
|
+
# the service object.
|
33
|
+
# @param [Hash] options The list of the subscription options.
|
34
|
+
# @option options [Symbol] :prefix The prefix for the listener's callbacks.
|
35
|
+
# It defines the prefix to be added to a notification name
|
36
|
+
# to provide a corresponding listener method, that should be called by
|
37
|
+
# the publisher.
|
86
38
|
|
39
|
+
include Helpers::Parameters
|
87
40
|
# @api hide
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
41
|
+
private :params
|
42
|
+
private_class_method :allow_params
|
43
|
+
|
44
|
+
# @!scope class
|
45
|
+
# @!method allow_params(*names)
|
46
|
+
# @!visibility private
|
47
|
+
# Sets a list of allowed parameters for the class constructor and
|
48
|
+
# defines the corresponding instance attributes.
|
49
|
+
#
|
50
|
+
# @example
|
51
|
+
# class MyService < Hexx::Service
|
52
|
+
# allows_params :name
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# service = MyService.new name: "name", code: "code"
|
56
|
+
# service.send :name # => "name"
|
57
|
+
# service.send :params # => { "name" => "name" }
|
58
|
+
#
|
59
|
+
# @param [Symbol, String, Array<Symbol, String>] names
|
60
|
+
# The list of allowed parameters.
|
95
61
|
|
96
62
|
# @!attribute [r] params
|
63
|
+
# @!visibility private
|
97
64
|
# The list of service object parameters.
|
98
65
|
#
|
99
66
|
# The attribute is assigned via the {.new} method options.
|
100
67
|
# On initialization the parameters (keys) are stringified and whitelisted.
|
101
68
|
#
|
102
|
-
# Allowed parameters should be explicitly declared
|
69
|
+
# Allowed parameters should be explicitly declared via the {.allow_params}
|
70
|
+
# private class helper.
|
103
71
|
#
|
104
|
-
# @example
|
72
|
+
# @example
|
105
73
|
# class GetItem < Hexx::Service
|
106
74
|
# allow_params :name
|
107
75
|
# end
|
108
76
|
#
|
109
77
|
# service = GetItem.new name: "Олег", family: "Рюрикович"
|
110
78
|
# service.params # => { "name" => "Олег" }
|
79
|
+
#
|
111
80
|
# @return [Hash] the service object parameters.
|
112
81
|
|
82
|
+
include Helpers::Messages
|
83
|
+
# @api hide
|
84
|
+
public :messages
|
85
|
+
# @api hide
|
86
|
+
private :messages=, :add_message, :t
|
87
|
+
|
113
88
|
# @!attribute [r] messages
|
114
|
-
#
|
89
|
+
# @!visibility public
|
90
|
+
# The array of service messages (instances of {Hexx::Message})
|
115
91
|
# with +text+ and +type+ attributes.
|
116
92
|
#
|
117
|
-
# @
|
118
|
-
#
|
93
|
+
# @note The attribute setter is private!
|
94
|
+
#
|
95
|
+
# @example The messages can be added by the {#add_message} private helper
|
96
|
+
# class EditItem < Hexx::Service
|
119
97
|
# def run
|
120
|
-
#
|
98
|
+
# # ...
|
99
|
+
# else
|
100
|
+
# add_message "success", "changed"
|
101
|
+
# publish :changed, messages
|
121
102
|
# end
|
122
103
|
# end
|
123
104
|
#
|
124
105
|
# service = Test.new
|
125
|
-
# service.run
|
106
|
+
# service.run
|
126
107
|
# service.messages
|
127
|
-
# # => [#<Hexx::
|
108
|
+
# # => [#<Hexx::Message @type="info" @text="some_text" >]
|
128
109
|
#
|
129
|
-
# @return [Array<Hexx::
|
110
|
+
# @return [Array<Hexx::Message>] The array of messages.
|
130
111
|
|
131
|
-
|
112
|
+
# @!scope instance
|
113
|
+
# @!method add_message(type, text)
|
114
|
+
# @!visibility private
|
115
|
+
# Adds the translated message to the {#messages} array.
|
116
|
+
#
|
117
|
+
# @example
|
118
|
+
# class Hello < Hexx::Service
|
119
|
+
# def run
|
120
|
+
# add_message "success", "Hello!"
|
121
|
+
# publish :hello, messages
|
122
|
+
# end
|
123
|
+
# end
|
124
|
+
#
|
125
|
+
# hello = Hello.new
|
126
|
+
# hello.subscribe listener
|
127
|
+
# hello.run
|
128
|
+
#
|
129
|
+
# # The listener.hello [#<Hexx::Message @type="success", @text="Hello!" >]
|
130
|
+
# # will be called.
|
131
|
+
#
|
132
|
+
# @param [String] type The type of the message: "error", "info", "success"
|
133
|
+
# @param [String, Symbol] text The text of the message. The symbol will
|
134
|
+
# be translated using the {#t} method.
|
135
|
+
# @param [Hash] options The translation options.
|
136
|
+
# @return The updated {#messages} array.
|
132
137
|
|
133
|
-
# @!scope
|
138
|
+
# @!scope instance
|
139
|
+
# @!method t(text, options = {})
|
134
140
|
# @!visibility private
|
135
|
-
#
|
136
|
-
# Whitelists {#params} and declares a parameter for corresponding keys.
|
141
|
+
# Translates given key in current service's scope.
|
137
142
|
#
|
138
|
-
# @
|
143
|
+
# @note The method uses I18n.t library method.
|
139
144
|
#
|
140
|
-
# @example
|
141
|
-
# class
|
142
|
-
#
|
145
|
+
# @example Returns a translation if the first argument is a symbol.
|
146
|
+
# class PrintHello < Hexx::Service
|
147
|
+
# def run
|
148
|
+
# puts t(:hello)
|
149
|
+
# end
|
143
150
|
# end
|
144
151
|
#
|
145
|
-
#
|
146
|
-
#
|
152
|
+
# object = PrintHello.new
|
153
|
+
# object.run
|
154
|
+
# # => $ translation not found: en.activemodel.messages.models.test.name
|
155
|
+
#
|
156
|
+
# @example Returns the string argument.
|
157
|
+
# class PrintHello < Hexx::Service
|
158
|
+
# def run
|
159
|
+
# puts t("hello")
|
160
|
+
# end
|
161
|
+
# end
|
147
162
|
#
|
148
|
-
#
|
163
|
+
# object = PrintHello.new
|
164
|
+
# object.run
|
165
|
+
# # => $ name
|
166
|
+
#
|
167
|
+
# @param [Symbol, String] text The text to be translated.
|
168
|
+
# @param [Hash] options ({}) The translation options.
|
169
|
+
# @return [String] The translation.
|
149
170
|
|
150
|
-
|
151
|
-
#
|
152
|
-
|
153
|
-
|
154
|
-
#
|
171
|
+
include Helpers::Validations
|
172
|
+
# @api hide
|
173
|
+
private :validate!
|
174
|
+
|
175
|
+
# @!scope class
|
176
|
+
# @!method validates(attribute, options)
|
177
|
+
# @!visibility private
|
178
|
+
# Adds a standard validation for the attribute.
|
155
179
|
#
|
156
|
-
# @
|
157
|
-
# @param [
|
158
|
-
#
|
159
|
-
#
|
160
|
-
#
|
180
|
+
# @param [Symbol, String] attribute The name of the attribute to validate.
|
181
|
+
# @param [Hash] options The list of validation options.
|
182
|
+
# @see
|
183
|
+
# http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validates
|
184
|
+
# ActiveModel validations APIdocs
|
161
185
|
|
162
|
-
#
|
163
|
-
#
|
186
|
+
# @!scope class
|
187
|
+
# @!method validate(method, options)
|
188
|
+
# @!visibility private
|
189
|
+
# Adds a custom validation (calls given method).
|
164
190
|
#
|
165
|
-
#
|
166
|
-
|
167
|
-
|
191
|
+
# @param [Symbol, String] method The name of the validation method.
|
192
|
+
# @param [Hash] options The list of validation options.
|
193
|
+
# @see
|
194
|
+
# http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validate
|
195
|
+
# ActiveModel validations APIdocs
|
168
196
|
|
169
|
-
#
|
197
|
+
# @!scope instance
|
198
|
+
# @!method validate!
|
199
|
+
# @!visibility private
|
200
|
+
# Runs validations and raises <tt>Hexx::ServiceInvalid</tt>
|
201
|
+
# when a validation fails.
|
170
202
|
#
|
171
|
-
# @example
|
172
|
-
#
|
173
|
-
#
|
174
|
-
#
|
175
|
-
#
|
203
|
+
# @example (see Hexx::ServiceInvalid)
|
204
|
+
#
|
205
|
+
# @example Safe usage (recommended) with the {#escape} wrapper.
|
206
|
+
# service GetItem < Hexx::Service
|
207
|
+
# allow_params :uuid
|
208
|
+
# validates :uuid, presence: true
|
209
|
+
# def run
|
210
|
+
# escape { validate! }
|
176
211
|
# end
|
177
212
|
# end
|
178
213
|
#
|
179
214
|
# service = GetItem.new
|
180
|
-
# service.
|
181
|
-
# # => false
|
215
|
+
# service.run # => publishes :error notification
|
182
216
|
#
|
183
|
-
#
|
184
|
-
|
185
|
-
|
217
|
+
# @raise [Hexx::ServiceInvalid] when the service object isn't valid.
|
218
|
+
|
219
|
+
include Helpers::Exceptions
|
220
|
+
# @api hide
|
221
|
+
private :escape, :on_error
|
222
|
+
private_class_method :raises
|
223
|
+
|
224
|
+
# @!scope class
|
225
|
+
# @!method raises(exceptions)
|
226
|
+
# @!visibility private
|
227
|
+
# Declares a list of specific +StandardError+ exceptions.
|
186
228
|
#
|
187
|
-
# @
|
188
|
-
#
|
189
|
-
|
190
|
-
|
191
|
-
|
229
|
+
# @example
|
230
|
+
# class Service < Hexx::Service
|
231
|
+
# raises :NotFound, :NotChanged
|
232
|
+
#
|
233
|
+
# def run
|
234
|
+
# run!
|
235
|
+
# rescue NotFound
|
236
|
+
# publish :not_found
|
237
|
+
# rescue NotChanged
|
238
|
+
# publish :not_changed
|
239
|
+
# rescue => err
|
240
|
+
# # works out any other (unspecified exceptions)
|
241
|
+
# publish :error
|
242
|
+
# else
|
243
|
+
# # works out the main scenario
|
244
|
+
# publish :success
|
245
|
+
# end
|
246
|
+
# end
|
247
|
+
#
|
248
|
+
# Service.const_defined? :NotFound # => true
|
249
|
+
# Service.const_defined? :NotChanged # => true
|
250
|
+
#
|
251
|
+
# exception = Service::NotFound.new
|
252
|
+
# exception.is_a? StandardError # => true
|
253
|
+
#
|
254
|
+
# @param [String, Symbol, Array<String, Symbol>] exceptions The list of
|
255
|
+
# specific +StandardError+ exceptions.
|
192
256
|
|
193
|
-
|
257
|
+
# @!scope instance
|
258
|
+
# @!method escape
|
259
|
+
# @!visibility private
|
260
|
+
# The method re-raises +StandardError+ exceptions as a
|
261
|
+
# <tt>Hexx::ServiceInvalid</tt>.
|
262
|
+
#
|
263
|
+
# * rescues from a +StandardError+ exceptions
|
264
|
+
# * adds error message to the service
|
265
|
+
# * re-raises the <tt>Hexx::ServiceInvalid</tt> exception
|
266
|
+
#
|
267
|
+
# @example
|
268
|
+
# class GetItem < Hexx::Service
|
269
|
+
# def run
|
270
|
+
# escape { do_something_unsafe }
|
271
|
+
# rescue => err
|
272
|
+
# publish :error, err.messages
|
273
|
+
# end
|
274
|
+
# publish :success
|
275
|
+
# end
|
276
|
+
# end
|
277
|
+
#
|
278
|
+
# @yield the block.
|
279
|
+
# @raise [Hexx::ServiceInvalid] if the block raised the +StandardError+.
|
280
|
+
# @return the value returned by the block.
|
194
281
|
|
195
|
-
|
282
|
+
# @!scope instance
|
283
|
+
# @!method on_error(messages)
|
284
|
+
# @!visibility private
|
285
|
+
# Raises the {Hexx::ServiceInvalid} exception, populated with given
|
286
|
+
# messages.
|
287
|
+
#
|
288
|
+
# @example
|
289
|
+
# class EditItem < Hexx::Service
|
290
|
+
#
|
291
|
+
# allow_params :id, :name
|
292
|
+
# # ...
|
293
|
+
#
|
294
|
+
# def find_item
|
295
|
+
# run_service GetItem, :on_item, id: id
|
296
|
+
# end
|
297
|
+
#
|
298
|
+
# def on_item_not_found(*, messages)
|
299
|
+
# on_error(messages) # Raises Hexx::ServiceInvalid
|
300
|
+
# end
|
301
|
+
# end
|
302
|
+
#
|
303
|
+
# @param [Array<Hexx::ServiceInvalid>] messages The list of error
|
304
|
+
# messages to be added to the exception.
|
305
|
+
# @raise [Hexx::ServiceInvalid] the exception.
|
196
306
|
|
197
|
-
#
|
198
|
-
#
|
199
|
-
|
200
|
-
|
307
|
+
# @!scope class
|
308
|
+
# @!method new(params = {})
|
309
|
+
# Constructs a service object with given parameters.
|
310
|
+
#
|
311
|
+
# @example (see Hexx::Service)
|
312
|
+
# @param [Hash] params ({}) The parameters of the service object to be
|
313
|
+
# assigned to the {#params} attribute.
|
314
|
+
# @return [Hexx::Service] The service object.
|
315
|
+
|
316
|
+
# @abstract
|
317
|
+
# Runs the service object.
|
318
|
+
def run
|
201
319
|
end
|
202
320
|
|
321
|
+
private
|
322
|
+
|
203
323
|
# The helper runs another service object and subscribes +self+ for the
|
204
324
|
# service object's notifications.
|
205
325
|
#
|
@@ -240,98 +360,29 @@ module Hexx
|
|
240
360
|
service.run
|
241
361
|
end
|
242
362
|
|
243
|
-
#
|
244
|
-
#
|
245
|
-
# The method:
|
246
|
-
# * rescues +StandardError+ exceptions
|
247
|
-
# * adds error message to the service
|
248
|
-
# * re-raises the <tt>Service::Invalid</tt> exception
|
363
|
+
# @api hide
|
364
|
+
# Makes private methods with given prefix public.
|
249
365
|
#
|
250
|
-
# @example
|
251
|
-
#
|
252
|
-
#
|
253
|
-
#
|
254
|
-
# rescue => err
|
255
|
-
# publish :error, err.messages
|
256
|
-
# end
|
366
|
+
# @example Opens private methods.
|
367
|
+
# def GetItem < Hexx::Service
|
368
|
+
# private
|
369
|
+
# def on_success
|
257
370
|
# publish :success
|
258
371
|
# end
|
259
372
|
# end
|
260
373
|
#
|
261
|
-
# @yield the block.
|
262
|
-
# @raise [Hexx::Service::Invalid] if the block raised the +StandardError+.
|
263
|
-
# @return the value returned by the block.
|
264
|
-
def escape
|
265
|
-
yield
|
266
|
-
rescue Invalid => err
|
267
|
-
raise err
|
268
|
-
rescue => err
|
269
|
-
errors.add :base, err.message
|
270
|
-
raise Invalid.new(self)
|
271
|
-
end
|
272
|
-
|
273
|
-
# Translates given key in current service's scope.
|
274
|
-
#
|
275
|
-
# @note The method uses I18n.t library method.
|
276
|
-
#
|
277
|
-
# @example Returns a translation if the first argument is a symbol.
|
278
|
-
# class Test < Hexx::Service
|
279
|
-
# end
|
280
|
-
# service = Test.new
|
281
|
-
# service.t :name
|
282
|
-
# # => "translation not found: en.activemodel.messages.models.test.name"
|
283
|
-
#
|
284
|
-
# @example Returns the string argument.
|
285
|
-
# service = Hexx::Service.new
|
286
|
-
# service.t "name"
|
287
|
-
# # => "name"
|
288
|
-
#
|
289
|
-
# @param [Symbol, String] text The text to be translated.
|
290
|
-
# @param [Hash] options The translation options.
|
291
|
-
# @return [String] The translation.
|
292
|
-
def t(text, options = {})
|
293
|
-
return text unless text.is_a? Symbol
|
294
|
-
scope = %w(activemodel messages models) << self.class.name.underscore
|
295
|
-
I18n.t text, options.merge(scope: scope)
|
296
|
-
end
|
297
|
-
|
298
|
-
attr_writer :messages
|
299
|
-
|
300
|
-
# Adds the translated message to the {#messages} array.
|
301
|
-
# @example (see Service#messages)
|
302
|
-
# @param [String] type The type of the message ("error", "info", "success")
|
303
|
-
# @param [String, Symbol] text The text of the message. The symbol will
|
304
|
-
# be translated using the {#t} method.
|
305
|
-
# @param [Hash] options The translation options.
|
306
|
-
# @return The updated {#messages} array.
|
307
|
-
def add_message(type, text, options = {})
|
308
|
-
messages << Message.new(type: type, text: t(text, options))
|
309
|
-
end
|
310
|
-
|
311
|
-
# Runs validations and fails if the service is invalid.
|
312
|
-
#
|
313
|
-
# @example (see Hexx::Service::Invalid)
|
314
|
-
#
|
315
|
-
# @example Safe usage (recommended) with the {#escape} wrapper.
|
316
|
-
# service GetItem < Hexx::Service
|
317
|
-
# allow_params :uuid
|
318
|
-
# validates :uuid, presence: true
|
319
|
-
# def run
|
320
|
-
# escape { validate! }
|
321
|
-
# end
|
322
|
-
# end
|
323
|
-
#
|
324
374
|
# service = GetItem.new
|
325
|
-
# service.
|
375
|
+
# service.respond_to? :on_success
|
376
|
+
# # => false
|
326
377
|
#
|
327
|
-
#
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
378
|
+
# service_with_callbacks = service.with_callbacks
|
379
|
+
# service_with_callbacks.respond_to? :on_success
|
380
|
+
# # => true
|
381
|
+
#
|
382
|
+
# @return [Hexx::Service::WithCallbacks<Hexx::Service>]
|
383
|
+
# The decorator that allows access to the service's private methods.
|
384
|
+
def with_callbacks(prefix: nil)
|
385
|
+
WithCallbacks.new(self, prefix: prefix)
|
335
386
|
end
|
336
387
|
end
|
337
388
|
end
|