hexx 5.4.0 → 6.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/README.rdoc +211 -81
- data/Rakefile +1 -2
- data/lib/hexx.rb +1 -0
- data/lib/hexx/{models.rb → coercible.rb} +10 -12
- data/lib/hexx/configurable.rb +101 -0
- data/lib/hexx/dependable.rb +51 -0
- data/lib/hexx/helpers/base.rb +111 -0
- data/lib/hexx/helpers/coersion.rb +82 -0
- data/lib/hexx/helpers/dependency.rb +87 -0
- data/lib/hexx/helpers/module_dependency.rb +57 -0
- data/lib/hexx/helpers/parameter.rb +40 -0
- data/lib/hexx/service.rb +96 -51
- data/lib/hexx/service/with_callbacks.rb +6 -7
- data/lib/hexx/version.rb +1 -1
- data/spec/hexx/coercible_spec.rb +56 -0
- data/spec/hexx/{dependencies_spec.rb → configurable_spec.rb} +7 -20
- data/spec/hexx/dependable_spec.rb +125 -0
- data/spec/hexx/service_spec.rb +24 -16
- metadata +16 -10
- data/lib/hexx/dependencies.rb +0 -182
- data/lib/hexx/models/base_coercer.rb +0 -44
- data/lib/hexx/service/parameters.rb +0 -81
- data/spec/hexx/models_spec.rb +0 -40
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Hexx
|
4
|
+
|
5
|
+
# Makes the class dependable from implementations through setter injections.
|
6
|
+
#
|
7
|
+
# Adds the private {#depends_on} helper method to the class.
|
8
|
+
# Basically the method is similar to the +attr_accessor+ with the following
|
9
|
+
# differencies:
|
10
|
+
#
|
11
|
+
# * it adds a semantics to the declaration.
|
12
|
+
# * it allows setting the default implementation.
|
13
|
+
# * dependency setters accepts classes and modules only and fails with
|
14
|
+
# the +TypeError+ otherwise.
|
15
|
+
# * dependency getters fails with the +NotImplemented+ error if the
|
16
|
+
# implementation hasn't been set.
|
17
|
+
# * if a default implementation is defined, the dependency cannot be
|
18
|
+
# set to +nil+.
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# class MyClass
|
22
|
+
# extend Hexx::Dependable
|
23
|
+
#
|
24
|
+
# depends_on :another_class, default: AnotherClass
|
25
|
+
# depends_on :looks_for_implementation
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# object = MyClass.new
|
29
|
+
# object.another_class # => AnotherClass
|
30
|
+
#
|
31
|
+
# object.looks_for_implementation
|
32
|
+
# # => fails with NotImplementedError
|
33
|
+
#
|
34
|
+
# object.looks_for_implementation = SomeInjection
|
35
|
+
# object.looks_for_implementation # => SomeInjection
|
36
|
+
module Dependable
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
# @!method depends_on(name, options = {})
|
41
|
+
# Declares the dependency with its default implementation.
|
42
|
+
# @example (see Hexx::Dependable)
|
43
|
+
# @param [String, Symbol] name The name of the dependency.
|
44
|
+
# @param [Hash] options ({}) The dependency declaration options.
|
45
|
+
# @option options [String, Symbol, Class] :default (nil) Optional default
|
46
|
+
# implementation for the dependency.
|
47
|
+
def depends_on(name, default: nil)
|
48
|
+
Helpers::Dependency.add self, name, default
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Hexx
|
4
|
+
|
5
|
+
# @api hide
|
6
|
+
# The module contains helper classes and modules.
|
7
|
+
#
|
8
|
+
# All the helpers injects some code into corresponding class or module.
|
9
|
+
#
|
10
|
+
# The content of the module is not a part of API, but its implementation
|
11
|
+
# details.
|
12
|
+
module Helpers
|
13
|
+
|
14
|
+
# @api hide
|
15
|
+
# @abstract
|
16
|
+
# The base class for attribute injection.
|
17
|
+
#
|
18
|
+
# The objects of the class validates its parameters and adds
|
19
|
+
# attribute's getter and setter into the target class or module.
|
20
|
+
class Base < Struct.new(:target, :name)
|
21
|
+
|
22
|
+
# @api hide
|
23
|
+
# @!method add(target, name)
|
24
|
+
# Injects an attribute to the target class.
|
25
|
+
#
|
26
|
+
# @param [Module] target The class or module to inject the attribute to.
|
27
|
+
# @param [String, Symbol] name The name of the attribute.
|
28
|
+
# @raise (see Hexx::Helpers::Base#validate)
|
29
|
+
# @return [Hexx::Helpers::Base] the base class object.
|
30
|
+
def self.add(*args)
|
31
|
+
new(*args).validate.add_getter.add_setter
|
32
|
+
end
|
33
|
+
|
34
|
+
# @api hide
|
35
|
+
# @!attribute target
|
36
|
+
# The class to inject the attribute to
|
37
|
+
# @return [Class] the target for the injection
|
38
|
+
|
39
|
+
# @api hide
|
40
|
+
# @!attribute name
|
41
|
+
# The name of the attribute to be created in a target class
|
42
|
+
# @return [Class] the name of the attribute
|
43
|
+
|
44
|
+
# @api hide
|
45
|
+
# Validates parameters of the dependency declaration.
|
46
|
+
#
|
47
|
+
# @raise (see Hexx::Helpers::Base#check_target)
|
48
|
+
# @raise (see Hexx::Helpers::Base#check_name_type)
|
49
|
+
# @raise (see Hexx::Helpers::Base#check_name_value)
|
50
|
+
# @return [Hexx::Helpers::Base] +self+
|
51
|
+
def validate
|
52
|
+
check_target
|
53
|
+
check_name_type
|
54
|
+
check_name_value
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
# @api hide
|
59
|
+
# Adds the parameter getter to the +target+ instance
|
60
|
+
# @return [Hexx::Helpers::Base] +self+
|
61
|
+
def add_getter
|
62
|
+
target.class_eval getter
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
66
|
+
# @api hide
|
67
|
+
# Adds the parameter setter to the +target+ instance
|
68
|
+
# @return [Hexx::Helpers::Base] +self+
|
69
|
+
def add_setter
|
70
|
+
target.class_eval setter
|
71
|
+
self
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
# @abstract
|
77
|
+
# @return [String] the getter definition
|
78
|
+
def getter
|
79
|
+
""
|
80
|
+
end
|
81
|
+
|
82
|
+
# @abstract
|
83
|
+
# @return [String] the setter definition
|
84
|
+
def setter
|
85
|
+
""
|
86
|
+
end
|
87
|
+
|
88
|
+
# @api hide
|
89
|
+
# @raise [TypeError] if a target to add the instance parameter to
|
90
|
+
# is not a class.
|
91
|
+
def check_target
|
92
|
+
return if target.is_a? Class
|
93
|
+
fail TypeError.new "#{ target.inspect } is not a class"
|
94
|
+
end
|
95
|
+
|
96
|
+
# @api hide
|
97
|
+
# @raise [TypeError] if the attribute name is neither a string nor symbol.
|
98
|
+
def check_name_type
|
99
|
+
return if name.is_a?(String) || name.is_a?(Symbol)
|
100
|
+
fail TypeError.new "#{ name.inspect } is neither string nor symbol"
|
101
|
+
end
|
102
|
+
|
103
|
+
# @api hide
|
104
|
+
# @raise [AttributeError] it the name is blank.
|
105
|
+
def check_name_value
|
106
|
+
return unless name.to_s == ""
|
107
|
+
fail ArgumentError.new "Dependency should have a name"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative "base"
|
3
|
+
|
4
|
+
module Hexx
|
5
|
+
module Helpers
|
6
|
+
|
7
|
+
# @api hide
|
8
|
+
# Coerces class attribute getter and setter with given type.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# Coersion.add MyClass, :name, Multibyte::Chars
|
12
|
+
# object = MyClass.new
|
13
|
+
#
|
14
|
+
# object.name = "Ivo"
|
15
|
+
# object.name
|
16
|
+
# # => #<Multibyte::Chars @wrapped_string="Ivo" >
|
17
|
+
class Coersion < Base
|
18
|
+
|
19
|
+
# @api hide
|
20
|
+
# @!scope class
|
21
|
+
# @!method add(target, name, type)
|
22
|
+
# Reloads the Base class initializer by adding the type of the attribute
|
23
|
+
# to coerce with.
|
24
|
+
#
|
25
|
+
# @example (see Hexx::Helpers::Coersion)
|
26
|
+
# @param (see Hexx::Helpers::Base.add)
|
27
|
+
# @param [Module] type The type of the attribute.
|
28
|
+
# @raise (see Hexx::Helpers::Coersion#validate)
|
29
|
+
# @return [Hexx::Helpers::Coersion] the coersion object.
|
30
|
+
def initialize(target, name, type)
|
31
|
+
super target, name
|
32
|
+
@type = type
|
33
|
+
end
|
34
|
+
|
35
|
+
# @!attribute type
|
36
|
+
# The type to coerce the attribute with
|
37
|
+
# @return [Class] the type of the attribute
|
38
|
+
attr_accessor :type
|
39
|
+
|
40
|
+
# @api hide
|
41
|
+
# Validates parameters of the coersion declaration.
|
42
|
+
#
|
43
|
+
# Adds validation of the coersion type to the
|
44
|
+
# {Hexx::Helper::Base#validate}.
|
45
|
+
#
|
46
|
+
# @raise (see Hexx::Helpers::Base.validate)
|
47
|
+
# @raise (see Hexx::Helpers::Coersion#check_type)
|
48
|
+
# @return [Hexx::Helpers::Coersion] +self+
|
49
|
+
def validate
|
50
|
+
check_type
|
51
|
+
super
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
# @api hide
|
57
|
+
# The definition of the coerced attribute getter.
|
58
|
+
# To be reloaded for ActiveRecord models.
|
59
|
+
def getter
|
60
|
+
"def #{ name }=(value);
|
61
|
+
@#{ name } = #{ type.name }.new(value);
|
62
|
+
end"
|
63
|
+
end
|
64
|
+
|
65
|
+
# @api hide
|
66
|
+
# The definition of the coerced attribute setter.
|
67
|
+
# To be reloaded for ActiveRecord models.
|
68
|
+
def setter
|
69
|
+
"def #{ name };
|
70
|
+
#{ type.name }.new(@#{ name });
|
71
|
+
end"
|
72
|
+
end
|
73
|
+
|
74
|
+
# @api hide
|
75
|
+
# @raise [TypeError] if type is not a class
|
76
|
+
def check_type
|
77
|
+
return if type.is_a? Class
|
78
|
+
fail TypeError.new "#{ type.inspect } is not a class"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative "base"
|
3
|
+
|
4
|
+
module Hexx
|
5
|
+
module Helpers
|
6
|
+
|
7
|
+
# @api hide
|
8
|
+
# @abstract
|
9
|
+
# The base class for both instance and module dependencies.
|
10
|
+
class Dependency < Base
|
11
|
+
|
12
|
+
# @api hide
|
13
|
+
# @!scope class
|
14
|
+
# @!method add(target, name, default)
|
15
|
+
# Reloads the Base class initializer by adding the default implementation
|
16
|
+
# for the dependency.
|
17
|
+
#
|
18
|
+
# @param (see Hexx::Helpers::Base)
|
19
|
+
# @param [Module] default The default implementation for the dependency.
|
20
|
+
# @raise (see Hexx::Helpers::Dependency#validate)
|
21
|
+
# @return [Hexx::Helpers::Dependency] the dependency object.
|
22
|
+
def initialize(target, name, default)
|
23
|
+
super target, name
|
24
|
+
@default = default
|
25
|
+
end
|
26
|
+
|
27
|
+
# @!attribute default
|
28
|
+
# The default implementation for the dependency
|
29
|
+
# @return [Module] the default implementation
|
30
|
+
attr_accessor :default
|
31
|
+
|
32
|
+
# @api hide
|
33
|
+
# Validates parameters for the dependency declaration.
|
34
|
+
#
|
35
|
+
# Adds validation of the dependency default implementation to the
|
36
|
+
# {Hexx::Helper::Base#validate}.
|
37
|
+
#
|
38
|
+
# @raise (see Hexx::Helpers::Base#validate)
|
39
|
+
# @raise (see Hexx::Helpers::Dependency#check_default)
|
40
|
+
# @return [Hexx::Helpers::Dependency] +self+
|
41
|
+
def validate
|
42
|
+
check_default
|
43
|
+
super
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# @api hide
|
49
|
+
# The dependency getter
|
50
|
+
def getter
|
51
|
+
"def #{ name };
|
52
|
+
@#{ name } ||= #{ default_name };
|
53
|
+
return @#{ name } if @#{ name };
|
54
|
+
fail NotImplementedError
|
55
|
+
.new \"DI: #{ target.name }##{ name } not implemented\";
|
56
|
+
end"
|
57
|
+
end
|
58
|
+
|
59
|
+
# @api hide
|
60
|
+
# The dependency setter
|
61
|
+
def setter
|
62
|
+
"def #{ name }=(value);
|
63
|
+
if value.nil? || value.is_a?(Module);
|
64
|
+
@#{ name } = value;
|
65
|
+
#{ name };
|
66
|
+
else;
|
67
|
+
fail TypeError.new \"DI: value.inspect is not a module\";
|
68
|
+
end;
|
69
|
+
end"
|
70
|
+
end
|
71
|
+
|
72
|
+
# @api hide
|
73
|
+
# @raise [TypeError] if the default implementation is neither a class,
|
74
|
+
# nor module
|
75
|
+
def check_default
|
76
|
+
return if default.nil? || default.is_a?(Module)
|
77
|
+
fail TypeError.new "#{ default.inspect } is neither a class nor module"
|
78
|
+
end
|
79
|
+
|
80
|
+
# @api hide
|
81
|
+
# Returns the name of the default implementation of the dependency.
|
82
|
+
def default_name
|
83
|
+
@default_name ||= default ? default.name : "nil"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative "dependency"
|
3
|
+
|
4
|
+
module Hexx
|
5
|
+
module Helpers
|
6
|
+
|
7
|
+
# @api hide
|
8
|
+
# Module dependency constructor.
|
9
|
+
#
|
10
|
+
# Adds the dependency to selected module.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# ModuleDependency.add(MyModule, :some_module, DefaultImplementation)
|
14
|
+
#
|
15
|
+
# MyModule.some_module
|
16
|
+
# # => DefaultImplementation
|
17
|
+
#
|
18
|
+
# MyModule.some_module = AnotherImplementation
|
19
|
+
# # => AnotherImplementation
|
20
|
+
#
|
21
|
+
# MyModule.some_module = 1
|
22
|
+
# # fails with #<TypeError @message="1 is not a module" >
|
23
|
+
class ModuleDependency < Dependency
|
24
|
+
|
25
|
+
# @api hide
|
26
|
+
# Adds the dependency to given module
|
27
|
+
# @example (see Hexx::Helpers::ModuleDependency)
|
28
|
+
# @param [Module] target The module to declare the dependency of.
|
29
|
+
# @param [String, Symbol] name The name of the dependency.
|
30
|
+
# @param [Module] default The default implementation of the dependency.
|
31
|
+
|
32
|
+
# @api hide
|
33
|
+
# Adds the module dependency getter
|
34
|
+
# @return [ModuleDependency] +self+.
|
35
|
+
def add_getter
|
36
|
+
target.instance_eval getter
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
# @api hide
|
41
|
+
# Adds the module dependency setter
|
42
|
+
# @return [ModuleDependency] +self+.
|
43
|
+
def add_setter
|
44
|
+
target.instance_eval setter
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# @raise [TypeError] if a target to add the dependency is not a module.
|
51
|
+
def check_target
|
52
|
+
return if target.is_a? Module
|
53
|
+
fail TypeError.new "#{ target.inspect } is not a module"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative "base"
|
3
|
+
|
4
|
+
module Hexx
|
5
|
+
module Helpers
|
6
|
+
|
7
|
+
# @api hide
|
8
|
+
# Adds setter and getter for the instance parameter.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# # Providing that MyClass#params returns a hash
|
12
|
+
# Parameter.add MyClass, :name
|
13
|
+
# object = MyClass.new
|
14
|
+
#
|
15
|
+
# object.params["name"] # => nil
|
16
|
+
# object.name # => nil
|
17
|
+
#
|
18
|
+
# object.params["name"] = "Ivan"
|
19
|
+
# object.params["name"] # => "Ivan"
|
20
|
+
# object.name # => "Ivan"
|
21
|
+
#
|
22
|
+
# object.name = "Ivo"
|
23
|
+
# object.params["name"] # => "Ivo"
|
24
|
+
# object.name # => "Ivo"
|
25
|
+
class Parameter < Base
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# @api hide
|
30
|
+
def setter
|
31
|
+
"def #{ name }; params[\"#{ name }\"]; end"
|
32
|
+
end
|
33
|
+
|
34
|
+
# @api hide
|
35
|
+
def getter
|
36
|
+
"def #{ name }=(value); params[\"#{ name }\"] = value; end"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/hexx/service.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
require_relative "dependable"
|
2
3
|
|
3
4
|
module Hexx
|
4
5
|
|
@@ -19,24 +20,99 @@ module Hexx
|
|
19
20
|
# service.run
|
20
21
|
# # => This will call the listener's method #on_found(item).
|
21
22
|
class Service
|
23
|
+
extend Dependable
|
22
24
|
include Wisper::Publisher
|
23
25
|
include ActiveModel::Validations
|
24
|
-
include Parameters
|
25
26
|
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
27
|
+
# @api hide
|
28
|
+
# Returns the list of allowed parameters for service objects.
|
29
|
+
#
|
30
|
+
# The parameters are added to the list by the {.allow_params} private
|
31
|
+
# helper method.
|
29
32
|
#
|
30
33
|
# @example
|
31
|
-
#
|
34
|
+
# class Service < Hexx::Service
|
35
|
+
# allow_params :name
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# Service.params # => "name"
|
39
|
+
#
|
40
|
+
# @return [Array<String>] The list of allowed instance parameters.
|
41
|
+
def self.params
|
42
|
+
@params ||= []
|
43
|
+
end
|
44
|
+
|
45
|
+
# @!scope class
|
46
|
+
# @!method validates(attribute, options)
|
47
|
+
# Adds a standard validation for the attribute.
|
48
|
+
# @param [Symbol, String] attribute The name of the attribute to validate.
|
49
|
+
# @param [Hash] options The list of validation options.
|
50
|
+
# @see ActiveModel validations {APIdocs}[
|
51
|
+
# http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validates]
|
52
|
+
|
53
|
+
# @!scope class
|
54
|
+
# @!method validate(method, options)
|
55
|
+
# Adds a custom validation (calls given method).
|
56
|
+
# @param [Symbol, String] method The name of the validation method.
|
57
|
+
# @param [Hash] options The list of validation options.
|
58
|
+
# @see ActiveModel validations {APIdocs}[
|
59
|
+
# http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validate]
|
60
|
+
|
61
|
+
# @!scope class
|
62
|
+
# @!method new(params = {})
|
63
|
+
# Constructs the service object with given parameters.
|
32
64
|
#
|
33
|
-
# @
|
65
|
+
# @example (see Hexx::Service)
|
66
|
+
# @param [Hash] params ({}) The parameters of the service object to be
|
67
|
+
# assigned to the {#params} attribute.
|
34
68
|
# @return [Hexx::Service] The service object.
|
35
|
-
|
36
|
-
|
69
|
+
|
70
|
+
# @api hide
|
71
|
+
# Initializes the service object.
|
72
|
+
# @param (see Hexx::Service.new)
|
73
|
+
# @return (see Hexx::Service.new)
|
74
|
+
def initialize(params = {})
|
75
|
+
@params = params.dup.stringify_keys.slice(*(self.class.params))
|
37
76
|
@messages = []
|
38
77
|
end
|
39
78
|
|
79
|
+
# @!attribute [r] params
|
80
|
+
# The list of service object parameters.
|
81
|
+
#
|
82
|
+
# The attribute is assigned via the {.new} method options.
|
83
|
+
# On initialization the parameters (keys) are stringified and whitelisted.
|
84
|
+
#
|
85
|
+
# Allowed parameters should be explicitly declared with the {.allow_params}.
|
86
|
+
#
|
87
|
+
# @example Only whitelisted params are being assigned.
|
88
|
+
# class GetItem < Hexx::Service
|
89
|
+
# allow_params :name
|
90
|
+
# end
|
91
|
+
#
|
92
|
+
# service = GetItem.new name: "Олег", family: "Рюрикович"
|
93
|
+
# service.params # => { "name" => "Олег" }
|
94
|
+
# @return [Hash] the service object parameters.
|
95
|
+
|
96
|
+
# @!attribute [r] messages
|
97
|
+
# The array of service messages (instances of {Hexx::Service::Message})
|
98
|
+
# with +text+ and +type+ attributes.
|
99
|
+
#
|
100
|
+
# @example
|
101
|
+
# class Test < Hexx::Service
|
102
|
+
# def run
|
103
|
+
# add_message "info", :ok
|
104
|
+
# end
|
105
|
+
# end
|
106
|
+
#
|
107
|
+
# service = Test.new
|
108
|
+
# service.run # adds message
|
109
|
+
# service.messages
|
110
|
+
# # => [#<Hexx::Service::Message @text="ok" @type="info" >]
|
111
|
+
#
|
112
|
+
# @return [Array<Hexx::Service::Message>] The array of messages.
|
113
|
+
|
114
|
+
attr_reader :params, :messages
|
115
|
+
|
40
116
|
# @!scope class
|
41
117
|
# @!visibility private
|
42
118
|
# @!method allow_params(*params)
|
@@ -54,28 +130,6 @@ module Hexx
|
|
54
130
|
#
|
55
131
|
# @param [Array<Symbol, String>] params The list of allowed keys.
|
56
132
|
|
57
|
-
# @!scope class
|
58
|
-
# @!method validates(attribute, options)
|
59
|
-
# Adds a standard validation for the attribute.
|
60
|
-
# @note The method is defined in the {ActiveModel::Validations} module.
|
61
|
-
|
62
|
-
# @!scope class
|
63
|
-
# @!method validate(method, options)
|
64
|
-
# Adds a custom validation (calls given method).
|
65
|
-
# @note The method is defined in the {ActiveModel::Validations} module.
|
66
|
-
|
67
|
-
# @!attribute params [r] The list of service object parameters.
|
68
|
-
# The attribute is assigned via the {.new} method options.
|
69
|
-
# The keys should be explicitly declared by the {.allow_params} helper.
|
70
|
-
#
|
71
|
-
# @example Only whitelisted params are being assigned.
|
72
|
-
# class GetItem < Hexx::Service
|
73
|
-
# allow_params :name
|
74
|
-
# end
|
75
|
-
#
|
76
|
-
# service = GetItem.new name: "Олег", family: "Рюрикович"
|
77
|
-
# service.params # => { "name" => "Олег" }
|
78
|
-
|
79
133
|
# @!method subscribe(listener, options = {})
|
80
134
|
# Subscribes the listener to service object's notifications.
|
81
135
|
# The <tt>:prefix</tt> sets the prefix to be added to a notification name
|
@@ -90,8 +144,8 @@ module Hexx
|
|
90
144
|
|
91
145
|
# @abstract
|
92
146
|
# Runs the service object.
|
93
|
-
#
|
94
|
-
#
|
147
|
+
#
|
148
|
+
# The method does nothing. To be reloaded by a specific service class.
|
95
149
|
def run
|
96
150
|
end
|
97
151
|
|
@@ -119,27 +173,18 @@ module Hexx
|
|
119
173
|
WithCallbacks.new(self, prefix: prefix)
|
120
174
|
end
|
121
175
|
|
122
|
-
# @!attribute [r] messages
|
123
|
-
# The array of service messages (instances of {Hexx::Service::Message})
|
124
|
-
# with +text+ and +type+ attributes.
|
125
|
-
#
|
126
|
-
# @example
|
127
|
-
# class Test < Hexx::Service
|
128
|
-
# def run
|
129
|
-
# add_message "info", :ok
|
130
|
-
# end
|
131
|
-
# end
|
132
|
-
#
|
133
|
-
# service = Test.new
|
134
|
-
# service.run # adds message
|
135
|
-
# service.messages
|
136
|
-
# # => [#<Hexx::Service::Message @text="ok" @type="info" >]
|
137
|
-
#
|
138
|
-
# @return [Array<Hexx::Service::Message>] The array of messages.
|
139
|
-
attr_reader :messages
|
140
|
-
|
141
176
|
private
|
142
177
|
|
178
|
+
# Sets a list of allowed parameters for the class constructor and
|
179
|
+
# defines the corresponding instance attributes.
|
180
|
+
#
|
181
|
+
# @example (see Hexx::Service::Parameters.params)
|
182
|
+
# @param [Array<Symbol, String>] keys The list of allowed parameters.
|
183
|
+
def self.allow_params(*keys)
|
184
|
+
@params = keys.map(&:to_s)
|
185
|
+
params.each { |name| Helpers::Parameter.add self, name }
|
186
|
+
end
|
187
|
+
|
143
188
|
# The helper runs another service object and subscribes +self+ for the
|
144
189
|
# service object's notifications.
|
145
190
|
#
|