hexx 5.4.0 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
#
|