good_services 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ab9aea86bdfee7c671ed7b0b880ca45f2599cf1b
4
- data.tar.gz: edb3d4af284f44bec355cd3d6e0e577716c015a1
3
+ metadata.gz: 3ba29e93e768c8a9b999b0b26ba0ec861610742d
4
+ data.tar.gz: 6bbe678af7397a8b9046b36e198cd3cb398fe05f
5
5
  SHA512:
6
- metadata.gz: 499c9fca7ab70df466f3ddf2bfa03156fd3c4f3bc4c630cfdf759b0bf1f00d86313940ffcfb51a60319addd6d5e39a6d7e08c881837f23653b40628c6d11998b
7
- data.tar.gz: fc6c806f50865d71f41720184ed440abecedfb7cd9bc0105146df016c7a70b67469966419f5785c405f95aef56e36605e25ae93ae59f58b56333a73135244cd6
6
+ metadata.gz: e21461365f61b0c4f5be9a0f091a8b6b9fde7a4a23df3ffd36aa4115c6caa99ca0183b141bbccd114f37f3690bfc28dda9869baa8006e1ffaf38a8cfd66fd2a4
7
+ data.tar.gz: c1b364fd4b13a7affd7fbbbcfcd296d3f9a73e725ad018d9f4494dac918e1c2f13246e7791bb9eca275da5917e8bb9085a1a9c097fe36e38e82255e09b4df631
data/Gemfile CHANGED
@@ -1,4 +1,7 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
+ ruby "2.3.0"
2
3
 
3
4
  # Specify your gem's dependencies in good_services.gemspec
4
5
  gemspec
6
+
7
+ gem "codeclimate-test-reporter", group: :test, require: nil
data/README.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # GoodServices
2
2
 
3
- This is a very simple gem I've created to keep the logic I've been frequently using in my apps to standardize my Service Objects. I intend to keep it as simple as possible so it can be versatile and easy to use, but ideas to improve it and pull-requests are welcome :)
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 = new_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
- **This syntax is not my masterpiece, I appreciate any ideas of a better way to do this.*
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
@@ -4,7 +4,7 @@ require "rake/testtask"
4
4
  Rake::TestTask.new(:test) do |t|
5
5
  t.libs << "test"
6
6
  t.libs << "lib"
7
- t.test_files = FileList['test/**/*_test.rb']
7
+ t.test_files = FileList['test/**/*_spec.rb']
8
8
  end
9
9
 
10
10
  task :default => :test
data/circle.yml ADDED
@@ -0,0 +1,8 @@
1
+ machine:
2
+ ruby:
3
+ version: 2.3.0
4
+ environment:
5
+ CODECLIMATE_REPO_TOKEN: 4f60d39541aca05c29688637baba3630f400c2c1fe9af5a8f6a385fa62541047
6
+ dependencies:
7
+ pre:
8
+ - gem install bundler -v 1.12.5
@@ -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
@@ -1,3 +1,3 @@
1
1
  module GoodServices
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  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.1.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: '1.12'
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: '1.12'
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.5.1
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