action_service 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +130 -0
- data/Rakefile +41 -0
- data/lib/action_service.rb +49 -0
- data/lib/action_service/version.rb +3 -0
- data/lib/generators/application_service/USAGE +6 -0
- data/lib/generators/application_service/application_service_generator.rb +18 -0
- data/lib/generators/application_service/templates/application_service.rb.tt +2 -0
- data/lib/generators/service/USAGE +6 -0
- data/lib/generators/service/service_generator.rb +21 -0
- data/lib/generators/service/templates/service.rb.tt +13 -0
- data/lib/tasks/action_service_tasks.rake +4 -0
- metadata +77 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0c8f7b52ecc3f88e50370f17d7cc24fd17e971a8
|
4
|
+
data.tar.gz: 2c3abf99ab662c10bdeca699313e301b78e301d1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 10d82df111bae4842bf47911c349e03d469f4d9ca0fbaa36eb532cc6005dde160afc61f1a30e4ca1243987ef03d58503b569b80daa1c8038de0c8a171cf4d75b
|
7
|
+
data.tar.gz: a033bd4d4b748c3bb10021d13e3e9a6dc39116d66db5980f705ba453da9ea8201935c876f59af41b9c36c0016b237aec68b032c3b18340e5cc1ee54ada2ad23a
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2018 abdofawzi
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
# ActionService v1.0
|
2
|
+
Welcome to Action Service gem, is a ruby gem to create and interact easily with services.
|
3
|
+
|
4
|
+
## Why services
|
5
|
+
Is where you can add your code to perform simple functionality instead of making complex controllers or models.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'action_service'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
```bash
|
21
|
+
$ gem install action_service
|
22
|
+
```
|
23
|
+
|
24
|
+
## Setting up
|
25
|
+
For start to use the gem execute:
|
26
|
+
```bash
|
27
|
+
$ rails g service:application_service
|
28
|
+
```
|
29
|
+
This command will generate application service (is the parent class for all your services), application service is inheriting from the action service base class, and you can overwrite all methods.
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
You can start to use action service by generating service to execute a specific logic, Example:
|
33
|
+
Run next command to generate service for authenticating an admin
|
34
|
+
```bash
|
35
|
+
$ rails g service Admin::Authenticate
|
36
|
+
```
|
37
|
+
this will add a new directory for admin inside `app/services` if not exist, and generate `authenticate_service.rb`
|
38
|
+
```bash
|
39
|
+
Running via Spring preloader in process 30051
|
40
|
+
create app/services/admin/authenticate_service.rb
|
41
|
+
```
|
42
|
+
And when you open `authenticate_service.rb` will be like this
|
43
|
+
```ruby
|
44
|
+
class Admin::AuthenticateService < ApplicationService
|
45
|
+
|
46
|
+
def initialize()
|
47
|
+
super()
|
48
|
+
end
|
49
|
+
|
50
|
+
def call
|
51
|
+
return self
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
### ApplicationService class
|
58
|
+
All generated services are inhariting from `ApplcaitonService`, `ApplicationService` is inherite from `ActoinService::Base, So all service will contain:
|
59
|
+
#### Three instance variables
|
60
|
+
1. `@success` is a boolean with `true` as default value , and if you add any error this flag will be changed to `false`.
|
61
|
+
2. `@errors` is a array contain a list if errors.
|
62
|
+
3. `@response` is a hash to add service response (values, objects, etc.).
|
63
|
+
#### Six instance methods
|
64
|
+
1. `success?` to get boolean if service excuted successfully ot not (based on adding errors).
|
65
|
+
2. `errors` to get list of errors.
|
66
|
+
3. `response` to get response hash.
|
67
|
+
4. `add_error(error_message)` to add error (will change `@success` to `false`), Example `add_error("wrong admin id")`.
|
68
|
+
5. `add_errors(*error_messages)` to add errors as parameters or array (will change `@success` to `false`), Example `add_errors("email is required","phone number is aready exist")` OR `add_errors(["email is required","phone number is aready exist"])`.
|
69
|
+
6. `add_errors_array(error_messages_array)` to add array of errors (will change `@success` to `false`), Example `add_errors_array(["email is required","phone number is aready exist"])`.
|
70
|
+
|
71
|
+
Now, let's implement `Admin::AuthenticateService`
|
72
|
+
```ruby
|
73
|
+
class Admin::AuthenticateService < ApplicationService
|
74
|
+
|
75
|
+
def initialize(email, password)
|
76
|
+
super()
|
77
|
+
@admin = Admin.find_by(email: email)
|
78
|
+
@password = password
|
79
|
+
end
|
80
|
+
|
81
|
+
def call
|
82
|
+
add_error "wrong admin email" and return sef if not @admin
|
83
|
+
add_error "wrong password" and return seld if not @admin.authenticate(@password)
|
84
|
+
@response[:admin] = @admin
|
85
|
+
return self
|
86
|
+
end
|
87
|
+
end
|
88
|
+
```
|
89
|
+
|
90
|
+
This service is now ready to be used, For example we will call the service inside a controller
|
91
|
+
```ruby
|
92
|
+
result = Admin::AuthenticateService.new(params[:email], params[:password]).call
|
93
|
+
if result.success?
|
94
|
+
# {success: true, response: {admin object}, errors: []}
|
95
|
+
render json: { success: result.success?, response: result.response, errors: result.errors }
|
96
|
+
else:
|
97
|
+
# {success: false, response: {}, errors: ["wrong email" OR "wrong password"]}
|
98
|
+
render json: { success: result.success?, response: result.response, errors: result.errors }, status: :unauthorized
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
102
|
+
#### Services layer will help you to write clean code, by small models, controller and DRY code (don't repeat yourself), you can use service inside another service and stop excuting the first service if the second one fails, Example:
|
103
|
+
```ruby
|
104
|
+
class Cache::List::AddHashService < ApplicationService
|
105
|
+
|
106
|
+
def initialize(list_key, hash_key, hash_data, expiry_datetime=nil)
|
107
|
+
super()
|
108
|
+
@list_key = list_key
|
109
|
+
@hash_key = hash_key
|
110
|
+
@hash = hash_data
|
111
|
+
@expiry_datetime = expiry_datetime
|
112
|
+
end
|
113
|
+
|
114
|
+
def call
|
115
|
+
result = Cache::Hash::SetService.new(hash_key, hash_data, @expiry_datetime).call
|
116
|
+
# if Cache::Hash::SetService fails will stop excuting and return the errors
|
117
|
+
add_errors result.errors and return self if not result.success?
|
118
|
+
result = Cache::List::AddService.new(list_key, hash_key, @expiry_datetime).call
|
119
|
+
# if Cache::List::AddService fails will stop excuting and return the errors
|
120
|
+
add_errors result.errors and return self if not result.success?
|
121
|
+
self
|
122
|
+
end
|
123
|
+
end
|
124
|
+
```
|
125
|
+
|
126
|
+
## Contributing
|
127
|
+
Bug reports and pull requests are welcome on GitHub at [https://github.com/abdofawzi5/action_service](https://github.com/abdofawzi5/action_service). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
128
|
+
|
129
|
+
## License
|
130
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'ActionService'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
require 'bundler/gem_tasks'
|
23
|
+
|
24
|
+
require 'rake/testtask'
|
25
|
+
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
27
|
+
t.libs << 'test'
|
28
|
+
t.pattern = 'test/**/*_test.rb'
|
29
|
+
t.verbose = false
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
task default: :test
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
begin
|
38
|
+
require 'gemika/tasks'
|
39
|
+
rescue LoadError
|
40
|
+
puts 'Run `gem install gemika` for additional tasks'
|
41
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'action_service/version'
|
2
|
+
require 'generators/service/service_generator'
|
3
|
+
require 'generators/application_service/application_service_generator'
|
4
|
+
|
5
|
+
module ActionService
|
6
|
+
|
7
|
+
|
8
|
+
# ActionService::Base is the parent class for all services that will be generated.
|
9
|
+
class Base
|
10
|
+
def initialize
|
11
|
+
@errors = [] # contain errors
|
12
|
+
@response = {} # contain the service response data
|
13
|
+
@success = true # flag service execution without any error
|
14
|
+
end
|
15
|
+
|
16
|
+
def errors
|
17
|
+
@errors
|
18
|
+
end
|
19
|
+
|
20
|
+
def response
|
21
|
+
@response
|
22
|
+
end
|
23
|
+
|
24
|
+
def success?
|
25
|
+
@success
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_error(error_message)
|
29
|
+
@success = false
|
30
|
+
@errors << error_message
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_errors(*error_messages)
|
34
|
+
@success = false
|
35
|
+
if error_messages[0].kind_of?(Array)
|
36
|
+
# called using array
|
37
|
+
add_errors_array(error_messages[0])
|
38
|
+
else
|
39
|
+
@errors += error_messages
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_errors_array(error_messages_array)
|
44
|
+
@success = false
|
45
|
+
@errors += error_messages_array
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Service
|
2
|
+
class ApplicationServiceGenerator < Rails::Generators::Base
|
3
|
+
|
4
|
+
source_root File.expand_path("templates", __dir__)
|
5
|
+
|
6
|
+
def create_application_service
|
7
|
+
template "application_service.rb", application_service_file_name
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def application_service_file_name
|
13
|
+
@application_record_file_name ||= "app/services/application_service.rb"
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Service
|
2
|
+
class ServiceGenerator < Rails::Generators::NamedBase
|
3
|
+
|
4
|
+
source_root File.expand_path('templates', __dir__)
|
5
|
+
|
6
|
+
def create_service_file
|
7
|
+
template 'service.rb.tt', File.join('app/services', class_path, "#{file_name}_service.rb")
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def file_name
|
13
|
+
@_file_name ||= remove_possible_suffix(super)
|
14
|
+
end
|
15
|
+
|
16
|
+
def remove_possible_suffix(name)
|
17
|
+
name.sub(/_?service$/i, "")
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: action_service
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Abdo Fawzi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-10-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
- - "<="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '6'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.0'
|
30
|
+
- - "<="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '6'
|
33
|
+
description: Is where you can add your code to do simple functionality instead of
|
34
|
+
make complex controller or models.
|
35
|
+
email:
|
36
|
+
- abdofawzi5@gmail.com
|
37
|
+
executables: []
|
38
|
+
extensions: []
|
39
|
+
extra_rdoc_files: []
|
40
|
+
files:
|
41
|
+
- MIT-LICENSE
|
42
|
+
- README.md
|
43
|
+
- Rakefile
|
44
|
+
- lib/action_service.rb
|
45
|
+
- lib/action_service/version.rb
|
46
|
+
- lib/generators/application_service/USAGE
|
47
|
+
- lib/generators/application_service/application_service_generator.rb
|
48
|
+
- lib/generators/application_service/templates/application_service.rb.tt
|
49
|
+
- lib/generators/service/USAGE
|
50
|
+
- lib/generators/service/service_generator.rb
|
51
|
+
- lib/generators/service/templates/service.rb.tt
|
52
|
+
- lib/tasks/action_service_tasks.rake
|
53
|
+
homepage: https://github.com/abdofawzi5/action_service
|
54
|
+
licenses:
|
55
|
+
- MIT
|
56
|
+
metadata: {}
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options: []
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
requirements: []
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 2.5.2
|
74
|
+
signing_key:
|
75
|
+
specification_version: 4
|
76
|
+
summary: Is a ruby gem to create and interact easily with services.
|
77
|
+
test_files: []
|