service-objecter 1.0.1
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 +7 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +113 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/service_objecter.rb +70 -0
- data/lib/service_objecter/chainit_integration.rb +31 -0
- data/lib/service_objecter/result.rb +34 -0
- data/lib/service_objecter/version.rb +3 -0
- data/service_objecter.gemspec +27 -0
- metadata +101 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 57106416b9e845a3ba712be54cc61f56cf1d8a9c
|
4
|
+
data.tar.gz: ed9f9ec2225f398483588bfa4cd94b8438434fb4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d6d012ab9ca388b19187db3fb8961a2f157870d6169a9e1b56db6f4441e4227c98d9b41232ba03537d472dd9ac5c32d222491e312a73de6b5f103d41afcb2012
|
7
|
+
data.tar.gz: 7637a2b110650b5023285974032a165e9fc3b15ada5024886c4e7fb91e22259779b914746c6c037b7bb97b6bee37f710f97da6d175784eea457d58dab595053e
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 btolarz
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
# ServiceObjecter
|
2
|
+
|
3
|
+
[](https://circleci.com/gh/tier-tools/service_objecter/tree/master)
|
4
|
+
|
5
|
+
## Description
|
6
|
+
|
7
|
+
Simple module, to tidy service objects.
|
8
|
+
|
9
|
+
You can read our guide how we think service objects should works [The best service object (for us)](https://github.com/tier-tools/service_objecter/wiki/The-best-service-object-(for-us))
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
### Always call service object in one way, ex. by `call` method.
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
class Service
|
17
|
+
def call
|
18
|
+
puts 'hello'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Service.new.call
|
23
|
+
```
|
24
|
+
|
25
|
+
To simplify this ServiceObjecter provides some shortcuts
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
class Service
|
29
|
+
include ServiceObjecter
|
30
|
+
def call
|
31
|
+
puts 'hello'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
Service.call
|
36
|
+
```
|
37
|
+
|
38
|
+
### Returns result object as Result struct object
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
class Service
|
42
|
+
include ServiceObjecter
|
43
|
+
|
44
|
+
def call
|
45
|
+
puts 'hello'
|
46
|
+
success('some value')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
service = Service.call
|
51
|
+
service.success? #=> true
|
52
|
+
service.failure? #=> false
|
53
|
+
service.value #=> 'some value'
|
54
|
+
```
|
55
|
+
|
56
|
+
With ServiceObjecter You can end call in many ways
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
success(:optional_value)
|
60
|
+
failed(:optional_value)
|
61
|
+
Result.new(
|
62
|
+
true, #=> success?
|
63
|
+
'optional_value'
|
64
|
+
)
|
65
|
+
```
|
66
|
+
|
67
|
+
## Full example
|
68
|
+
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
class Service
|
72
|
+
include ServiceObjecter
|
73
|
+
|
74
|
+
def call(params) #=> instead of passing params to #new, do it in #call
|
75
|
+
a = params[:a]
|
76
|
+
# do something important
|
77
|
+
Result.new(true, a)# return result object
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
params = {a: 1}
|
82
|
+
service = Service.call(params)
|
83
|
+
|
84
|
+
if service.success?
|
85
|
+
puts service.value
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
89
|
+
## ChainIt integration
|
90
|
+
|
91
|
+
Install `ChainIt` to get more power of service objects.
|
92
|
+
Read more [ChainIt gem](https://github.com/tier-tools/ChainIt)
|
93
|
+
With `ServiceObjecter` you get shortcuts.
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
class Service
|
97
|
+
include ServiceObjecter
|
98
|
+
|
99
|
+
def call(params)
|
100
|
+
chain { some method }
|
101
|
+
chain { other method }
|
102
|
+
result
|
103
|
+
end
|
104
|
+
end
|
105
|
+
```
|
106
|
+
|
107
|
+
## Contributing
|
108
|
+
|
109
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/tier-tools/service_objecter.
|
110
|
+
|
111
|
+
## License
|
112
|
+
|
113
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'service_objecter'
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require 'irb'
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'service_objecter/result'
|
2
|
+
require 'service_objecter/chainit_integration'
|
3
|
+
|
4
|
+
module ServiceObjecter
|
5
|
+
def self.included(klass)
|
6
|
+
klass.extend(ClassMethods)
|
7
|
+
klass.singleton_class.prepend(ChainitIntegration) if defined?(ChainIt)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def call(*args)
|
12
|
+
new.call(*args)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def call
|
17
|
+
raise NotImplementedError
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def success(value = nil)
|
23
|
+
result.push(true, value)
|
24
|
+
end
|
25
|
+
|
26
|
+
def failed(value = nil)
|
27
|
+
result.push(false, value)
|
28
|
+
end
|
29
|
+
|
30
|
+
def crashed(error, value = nil)
|
31
|
+
log(error)
|
32
|
+
failed value || error
|
33
|
+
end
|
34
|
+
|
35
|
+
def log(data)
|
36
|
+
return unless defined?(Rails)
|
37
|
+
Rails.logger.error data
|
38
|
+
end
|
39
|
+
|
40
|
+
def result
|
41
|
+
@result ||= Result.new(true)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Transactions helper
|
45
|
+
# Simple usage
|
46
|
+
#
|
47
|
+
# def call
|
48
|
+
# with_transaction do
|
49
|
+
# ChainIt.new.chain { failed }.result
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# def call
|
54
|
+
# with_transaction do
|
55
|
+
# failed
|
56
|
+
# end
|
57
|
+
# end
|
58
|
+
|
59
|
+
def with_transaction
|
60
|
+
return yield unless defined?(ActiveRecord)
|
61
|
+
result = nil
|
62
|
+
ActiveRecord::Base.transaction(requires_new: true) do
|
63
|
+
result = yield
|
64
|
+
raise ActiveRecord::Rollback if result.failure?
|
65
|
+
end
|
66
|
+
result
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
require 'service_objecter/version'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
module ServiceObjecter
|
3
|
+
module ChainitIntegration
|
4
|
+
extend(Forwardable)
|
5
|
+
|
6
|
+
def self.prepended(klass)
|
7
|
+
klass.extend(ClassMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def call(*args)
|
12
|
+
service = new
|
13
|
+
service.send :__set_chain__
|
14
|
+
service.call(*args)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def_delegators :@__chain__, :chain, :skip_next, :on_error, :result
|
19
|
+
alias run chain
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def __set_chain__
|
24
|
+
@__chain__ = ChainIt.new
|
25
|
+
end
|
26
|
+
|
27
|
+
def __get_chain__
|
28
|
+
@__chain__
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module ServiceObjecter
|
2
|
+
class Result
|
3
|
+
def initialize(success, value = nil)
|
4
|
+
@success, @value = success, value
|
5
|
+
end
|
6
|
+
|
7
|
+
def push(success, value = nil)
|
8
|
+
@success = success
|
9
|
+
store.merge!(value) if value.is_a?(Hash)
|
10
|
+
@value = value
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
def success?
|
15
|
+
@success
|
16
|
+
end
|
17
|
+
|
18
|
+
def failure?
|
19
|
+
!@success
|
20
|
+
end
|
21
|
+
|
22
|
+
def value
|
23
|
+
@value
|
24
|
+
end
|
25
|
+
|
26
|
+
def [](val)
|
27
|
+
@store[val]
|
28
|
+
end
|
29
|
+
|
30
|
+
def store
|
31
|
+
@store ||= Hash.new
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'service_objecter/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'service-objecter'
|
8
|
+
spec.version = ServiceObjecter::VERSION
|
9
|
+
spec.authors = %w[btolarz nnande]
|
10
|
+
spec.email = ['btolarz@gmail.com']
|
11
|
+
|
12
|
+
spec.summary = 'Easy way to create service objects'
|
13
|
+
spec.description = 'Easy way to create service objects'
|
14
|
+
spec.homepage = 'https://github.com/tier-tools/service_objecter'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = 'exe'
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ['lib']
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.14'
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: service-objecter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- btolarz
|
8
|
+
- nnande
|
9
|
+
autorequire:
|
10
|
+
bindir: exe
|
11
|
+
cert_chain: []
|
12
|
+
date: 2018-11-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.14'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.14'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '10.0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '10.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '3.0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '3.0'
|
56
|
+
description: Easy way to create service objects
|
57
|
+
email:
|
58
|
+
- btolarz@gmail.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".gitignore"
|
64
|
+
- ".rspec"
|
65
|
+
- ".travis.yml"
|
66
|
+
- Gemfile
|
67
|
+
- LICENSE.txt
|
68
|
+
- README.md
|
69
|
+
- Rakefile
|
70
|
+
- bin/console
|
71
|
+
- bin/setup
|
72
|
+
- lib/service_objecter.rb
|
73
|
+
- lib/service_objecter/chainit_integration.rb
|
74
|
+
- lib/service_objecter/result.rb
|
75
|
+
- lib/service_objecter/version.rb
|
76
|
+
- service_objecter.gemspec
|
77
|
+
homepage: https://github.com/tier-tools/service_objecter
|
78
|
+
licenses:
|
79
|
+
- MIT
|
80
|
+
metadata: {}
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
requirements: []
|
96
|
+
rubyforge_project:
|
97
|
+
rubygems_version: 2.6.14
|
98
|
+
signing_key:
|
99
|
+
specification_version: 4
|
100
|
+
summary: Easy way to create service objects
|
101
|
+
test_files: []
|