good_services 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +4 -1
- data/README.md +39 -3
- data/Rakefile +1 -1
- data/circle.yml +8 -0
- data/good_services.gemspec +1 -1
- data/lib/generators/good_services/service_generator.rb +64 -0
- data/lib/generators/good_services/templates/namespaced_service.erb +21 -0
- data/lib/generators/good_services/templates/namespaceless_service.erb +19 -0
- data/lib/good_services/version.rb +1 -1
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ba29e93e768c8a9b999b0b26ba0ec861610742d
|
4
|
+
data.tar.gz: 6bbe678af7397a8b9046b36e198cd3cb398fe05f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e21461365f61b0c4f5be9a0f091a8b6b9fde7a4a23df3ffd36aa4115c6caa99ca0183b141bbccd114f37f3690bfc28dda9869baa8006e1ffaf38a8cfd66fd2a4
|
7
|
+
data.tar.gz: c1b364fd4b13a7affd7fbbbcfcd296d3f9a73e725ad018d9f4494dac918e1c2f13246e7791bb9eca275da5917e8bb9085a1a9c097fe36e38e82255e09b4df631
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# GoodServices
|
2
2
|
|
3
|
-
|
3
|
+
[![Code Climate](https://codeclimate.com/github/victoryam/good_services/badges/gpa.svg)](https://codeclimate.com/github/victoryam/good_services) [![Gem Version](https://badge.fury.io/rb/good_services.svg)](https://badge.fury.io/rb/good_services) ![Build](https://circleci.com/gh/victoryam/good_services.svg?style=shield) [![Test Coverage](https://codeclimate.com/github/victoryam/good_services/badges/coverage.svg?no_cache)](https://codeclimate.com/github/victoryam/good_services/coverage)
|
4
|
+
|
5
|
+
This is a very simple gem I've created to keep the logic I've been frequently using in my apps Service Objects.
|
6
|
+
|
7
|
+
I intend to keep it as simple as possible so it can be versatile and easy to use, but ideas and pull-requests are welcome :)
|
4
8
|
|
5
9
|
## Installation
|
6
10
|
|
@@ -59,8 +63,39 @@ module Pet
|
|
59
63
|
end
|
60
64
|
end
|
61
65
|
|
66
|
+
```
|
67
|
+
#### Generators
|
68
|
+
|
69
|
+
When using Rails you can use our generator to get a simple Service boilerplate:
|
70
|
+
```
|
71
|
+
rails generate good_services:service PetRenamer
|
72
|
+
```
|
73
|
+
|
74
|
+
If you prefer using namespaces for your services (**we recommend it**), you can use it like that:
|
75
|
+
|
76
|
+
```
|
77
|
+
rails generate good_services:service Pets::Renamer
|
62
78
|
```
|
63
79
|
|
80
|
+
#### Basic usage
|
81
|
+
|
82
|
+
The **run** method is considered the safe way to run the service (always returns true or false)
|
83
|
+
```ruby
|
84
|
+
Pet::Renamer.run(pet: Pet.new, name: "Flipsy")
|
85
|
+
# => true
|
86
|
+
|
87
|
+
Pet::Renamer.run(pet: nil, name: "Flipsy")
|
88
|
+
# => false
|
89
|
+
```
|
90
|
+
|
91
|
+
The **run!** method does the same, except that it doesn't rescue any errors (always returns true or raises an exception)
|
92
|
+
```ruby
|
93
|
+
Pet::Renamer.run!(pet: Pet.new, name: "Flipsy")
|
94
|
+
# => true
|
95
|
+
|
96
|
+
Pet::Renamer.run!(pet: nil, name: "Flipsy")
|
97
|
+
# => InvalidPetError
|
98
|
+
```
|
64
99
|
|
65
100
|
#### By default the following variables are available as attr_readers:
|
66
101
|
|
@@ -98,10 +133,11 @@ The exception will be saved in the **@error** variable and accessible to the out
|
|
98
133
|
#### Perform
|
99
134
|
The only required method for your service is the **perform** method.
|
100
135
|
It will have the logic called by your .run and .run! methods.
|
136
|
+
**Try to always use methods that raise exceptions, like the example below (in Rails)**
|
101
137
|
|
102
138
|
```ruby
|
103
139
|
def perform
|
104
|
-
@record.name
|
140
|
+
@record.update!(name: new_name)
|
105
141
|
end
|
106
142
|
```
|
107
143
|
|
@@ -115,7 +151,7 @@ def validate
|
|
115
151
|
raise NoNewNameError unless new_name
|
116
152
|
end
|
117
153
|
```
|
118
|
-
**
|
154
|
+
**I'm not proud of this syntax, I appreciate any insights on a better way to do this.*
|
119
155
|
|
120
156
|
---
|
121
157
|
|
data/Rakefile
CHANGED
data/circle.yml
ADDED
data/good_services.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
-
spec.add_development_dependency "bundler", "~> 1.12"
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.12.5"
|
24
24
|
spec.add_development_dependency "rake", "~> 10.0"
|
25
25
|
spec.add_development_dependency "minitest", "~> 5.0"
|
26
26
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module GoodServices
|
2
|
+
module Generators
|
3
|
+
class ServiceGenerator < Rails::Generators::NamedBase
|
4
|
+
desc "Creates a GoodServices basic service"
|
5
|
+
|
6
|
+
def create_service
|
7
|
+
if constants.size == 1
|
8
|
+
create_file service_path, namespaceless_template
|
9
|
+
elsif constants.size == 2
|
10
|
+
create_file service_path, namespaced_template
|
11
|
+
else
|
12
|
+
puts
|
13
|
+
puts "[Error] This generator only supports one level of namespacing!"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def namespaceless_template
|
20
|
+
get_template("namespaceless_service").result(binding)
|
21
|
+
end
|
22
|
+
|
23
|
+
def namespaced_template
|
24
|
+
get_template("namespaced_service").result(binding)
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_template(file)
|
28
|
+
path = File.expand_path("../templates/#{file}.erb", __FILE__)
|
29
|
+
ERB.new(File.read(path))
|
30
|
+
end
|
31
|
+
|
32
|
+
def service_path
|
33
|
+
if service_module
|
34
|
+
"app/services/#{module_name}/#{service_name}.rb"
|
35
|
+
else
|
36
|
+
"app/services/#{service_name}.rb"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Argument Helpers
|
42
|
+
#
|
43
|
+
def constants
|
44
|
+
class_name.split("::")
|
45
|
+
end
|
46
|
+
|
47
|
+
def service_module
|
48
|
+
@_service_module ||= constants.first if constants.size > 1
|
49
|
+
end
|
50
|
+
|
51
|
+
def service_class
|
52
|
+
@_service_class ||= class_name.split("::").last
|
53
|
+
end
|
54
|
+
|
55
|
+
def service_name
|
56
|
+
@_service_name ||= service_class.underscore
|
57
|
+
end
|
58
|
+
|
59
|
+
def module_name
|
60
|
+
@_module_name ||= service_module.underscore
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module <%= service_module %>
|
2
|
+
class <%= service_class %> < GoodServices::Base
|
3
|
+
rescuable_from ActiveRecord::RecordInvalid
|
4
|
+
|
5
|
+
def initialize(record)
|
6
|
+
# Define your service parameters here
|
7
|
+
# We've set the 'record' parameter for you as an example
|
8
|
+
@record = record
|
9
|
+
end
|
10
|
+
|
11
|
+
def validate
|
12
|
+
# Add your validations here or delete this method
|
13
|
+
end
|
14
|
+
|
15
|
+
def perform
|
16
|
+
# Insert your service behaviour here
|
17
|
+
# The behaviour below is just an example
|
18
|
+
record.save!
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class <%= service_class %> < GoodServices::Base
|
2
|
+
rescuable_from ActiveRecord::RecordInvalid
|
3
|
+
|
4
|
+
def initialize(record)
|
5
|
+
# Define your service parameters here
|
6
|
+
# We've set the 'record' parameter for you as an example
|
7
|
+
@record = record
|
8
|
+
end
|
9
|
+
|
10
|
+
def validate
|
11
|
+
# Add your validations here or delete this method
|
12
|
+
end
|
13
|
+
|
14
|
+
def perform
|
15
|
+
# Insert your service behaviour here
|
16
|
+
# The behaviour below is just an example
|
17
|
+
record.save!
|
18
|
+
end
|
19
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: good_services
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Victor A.M.
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.12.5
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 1.12.5
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -68,7 +68,11 @@ files:
|
|
68
68
|
- Rakefile
|
69
69
|
- bin/console
|
70
70
|
- bin/setup
|
71
|
+
- circle.yml
|
71
72
|
- good_services.gemspec
|
73
|
+
- lib/generators/good_services/service_generator.rb
|
74
|
+
- lib/generators/good_services/templates/namespaced_service.erb
|
75
|
+
- lib/generators/good_services/templates/namespaceless_service.erb
|
72
76
|
- lib/good_services.rb
|
73
77
|
- lib/good_services/base.rb
|
74
78
|
- lib/good_services/version.rb
|
@@ -92,7 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
96
|
version: '0'
|
93
97
|
requirements: []
|
94
98
|
rubyforge_project:
|
95
|
-
rubygems_version: 2.
|
99
|
+
rubygems_version: 2.6.6
|
96
100
|
signing_key:
|
97
101
|
specification_version: 4
|
98
102
|
summary: A simple structure to help you build your service objects better and faster
|