service_record 1.3.0 → 1.4.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 +4 -4
- data/README.md +12 -12
- data/lib/service_record/base.rb +9 -15
- data/lib/service_record/response.rb +23 -0
- data/lib/service_record/version.rb +1 -1
- data/lib/service_record.rb +1 -0
- metadata +29 -48
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 66a63b54af431cc368206110f80b04419130698a73a412c0e803d0db5a543ee5
|
4
|
+
data.tar.gz: 19553c5c121484b683d076ed2937f6fb97f1e18cdbb6d15e8ce0482be59b0bed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c7b393c464c97bc71804d69a470d9e3b3a592b6cb68d51f13335075076e76804f68f45f0012846c5c651a56097b89de0924c0d702fddb0377c553c9a901dcce
|
7
|
+
data.tar.gz: 4b465a4ebe6db175aebb6ed12900a2468367f82ca4696e7d4daf1c39bf31aa19a63e3394c924da4e6485aa39b519a262947767fec7f2a45361d0c6ac663048c6
|
data/README.md
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# ServiceRecord
|
2
2
|
|
3
|
+
[](https://rubygems.org/gems/service_record)
|
3
4
|
[](https://github.com/uxxman/service_record/actions?query=workflow%3ACI)
|
4
5
|
[](https://codeclimate.com/github/uxxman/service_record)
|
5
6
|
[](https://codeclimate.com/github/uxxman/service_record)
|
6
|
-
[](https://rubygems.org/gems/service_record)
|
7
7
|
|
8
8
|
An ActiveRecord lookalike but for business model requirements, a.k.a Service Objects.
|
9
9
|
|
10
10
|
Rails is packed with amazing tools to get you started with building your new awesome project and enforces reliable and battle-tested guidelines. One of those guideline is "**thin controllers and fat models**", but sometimes (actually most of the time) its difficult to follow because most business requirements are not that simple like most CRUD operations.
|
11
11
|
|
12
|
-
Enters, ServiceRecord. Its similar to ActiveRecord models but their sole purpose is to perform a big/complex/muilt-step task without bloating the controllers or models.
|
12
|
+
Enters, ServiceRecord, a tiny wrapper around basic goodies included in Rails. Its similar to ActiveRecord models but their sole purpose is to perform a big/complex/muilt-step task without bloating the controllers or models.
|
13
13
|
|
14
14
|
## Installation
|
15
15
|
|
@@ -66,9 +66,7 @@ The returned response from a service will have the following useful attributes/m
|
|
66
66
|
* `result` contains returned value of service perform function
|
67
67
|
* `errors` contains details about issues that occurr while performing the service
|
68
68
|
|
69
|
-
There is a **perform!** (with a bang !) method which will raise **ServiceRecord::Failure** in case of service failure.
|
70
|
-
|
71
|
-
|
69
|
+
There is also a **perform!** (with a bang !) method which will raise **ServiceRecord::Failure** in case of service failure.
|
72
70
|
|
73
71
|
## Example
|
74
72
|
|
@@ -83,12 +81,12 @@ def sign_in
|
|
83
81
|
errors = []
|
84
82
|
|
85
83
|
# Basic validation
|
86
|
-
errors << 'Email is required'
|
87
|
-
errors << 'Email is invalid'
|
84
|
+
errors << 'Email is required' if params[:email].blank?
|
85
|
+
errors << 'Email is invalid' if params[:email].present? && /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i.match?(params[:email])
|
88
86
|
errors << 'Password is required' if params[:password].blank?
|
89
87
|
|
90
88
|
if errors.size == 0
|
91
|
-
user = User.find_by(email: params[:email])
|
89
|
+
user = User.find_by(email: params[:email])&.try(:authenticate, params[:password])
|
92
90
|
|
93
91
|
if user.present?
|
94
92
|
token = JsonWebToken.encode(user_id: user.id)
|
@@ -119,9 +117,11 @@ class AuthenticateUser < ApplicationService
|
|
119
117
|
def perform
|
120
118
|
user = User.find_by(email: email).try(:authenticate, password)
|
121
119
|
|
122
|
-
|
123
|
-
|
124
|
-
|
120
|
+
if user.present?
|
121
|
+
JsonWebToken.encode(user_id: user.id)
|
122
|
+
else
|
123
|
+
errors.add :authentication, 'invalid credentials'
|
124
|
+
end
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
@@ -174,7 +174,7 @@ Availble callbacks are `before_perform`, `after_perform` and `around_perform`. I
|
|
174
174
|
|
175
175
|
## Development
|
176
176
|
|
177
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake
|
177
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
178
178
|
|
179
179
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
180
180
|
|
data/lib/service_record/base.rb
CHANGED
@@ -2,13 +2,14 @@
|
|
2
2
|
|
3
3
|
require 'active_model'
|
4
4
|
require 'service_record/failure'
|
5
|
+
require 'service_record/response'
|
5
6
|
require 'service_record/callbacks'
|
6
7
|
|
7
8
|
module ServiceRecord
|
8
9
|
# Base class to be extended by all service classes
|
9
10
|
#
|
10
|
-
#
|
11
|
-
#
|
11
|
+
# class MyService < ServiceRecord
|
12
|
+
# end
|
12
13
|
#
|
13
14
|
class Base
|
14
15
|
include Callbacks
|
@@ -23,11 +24,14 @@ module ServiceRecord
|
|
23
24
|
def self.perform(args = {})
|
24
25
|
new.tap do |service|
|
25
26
|
service.attributes = args
|
26
|
-
break service unless service.valid?
|
27
27
|
|
28
|
-
service.
|
29
|
-
service.
|
28
|
+
if service.valid?
|
29
|
+
service.run_callbacks :perform do
|
30
|
+
service.result = service.perform
|
31
|
+
end
|
30
32
|
end
|
33
|
+
|
34
|
+
return Response.new(service.result, service.errors)
|
31
35
|
end
|
32
36
|
end
|
33
37
|
|
@@ -39,16 +43,6 @@ module ServiceRecord
|
|
39
43
|
raise Failure, service
|
40
44
|
end
|
41
45
|
|
42
|
-
# Checks the service for errors. Returns +true+ if no errors are found, +false+ otherwise.
|
43
|
-
def success?
|
44
|
-
errors.empty?
|
45
|
-
end
|
46
|
-
|
47
|
-
# Checks the service for errors. Returns +false+ if no errors are found, +true+ otherwise.
|
48
|
-
def failure?
|
49
|
-
!success?
|
50
|
-
end
|
51
|
-
|
52
46
|
# Each subclass must define the *perform* method
|
53
47
|
def perform
|
54
48
|
raise NotImplementedError
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ServiceRecord
|
4
|
+
# Response to be returned by a service when it finishes
|
5
|
+
class Response
|
6
|
+
attr_reader :result, :errors
|
7
|
+
|
8
|
+
def initialize(result, errors)
|
9
|
+
@result = result
|
10
|
+
@errors = errors
|
11
|
+
end
|
12
|
+
|
13
|
+
# Checks for errors. Returns +true+ if no errors are found, +false+ otherwise.
|
14
|
+
def success?
|
15
|
+
errors.empty?
|
16
|
+
end
|
17
|
+
|
18
|
+
# Checks for errors. Returns +false+ if no errors are found, +true+ otherwise.
|
19
|
+
def failure?
|
20
|
+
!success?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/service_record.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: service_record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Muhammad Usman
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-07-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -16,28 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '6.
|
19
|
+
version: '6.1'
|
20
20
|
type: :runtime
|
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: '6.
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: appraisal
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '2.3'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '2.3'
|
26
|
+
version: '6.1'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: rake
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -45,9 +31,6 @@ dependencies:
|
|
45
31
|
- - "~>"
|
46
32
|
- !ruby/object:Gem::Version
|
47
33
|
version: '13.0'
|
48
|
-
- - ">="
|
49
|
-
- !ruby/object:Gem::Version
|
50
|
-
version: 13.0.1
|
51
34
|
type: :development
|
52
35
|
prerelease: false
|
53
36
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -55,9 +38,6 @@ dependencies:
|
|
55
38
|
- - "~>"
|
56
39
|
- !ruby/object:Gem::Version
|
57
40
|
version: '13.0'
|
58
|
-
- - ">="
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version: 13.0.1
|
61
41
|
- !ruby/object:Gem::Dependency
|
62
42
|
name: rspec
|
63
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,102 +58,102 @@ dependencies:
|
|
78
58
|
requirements:
|
79
59
|
- - "~>"
|
80
60
|
- !ruby/object:Gem::Version
|
81
|
-
version: 0.5.
|
61
|
+
version: 0.5.2
|
82
62
|
type: :development
|
83
63
|
prerelease: false
|
84
64
|
version_requirements: !ruby/object:Gem::Requirement
|
85
65
|
requirements:
|
86
66
|
- - "~>"
|
87
67
|
- !ruby/object:Gem::Version
|
88
|
-
version: 0.5.
|
68
|
+
version: 0.5.2
|
89
69
|
- !ruby/object:Gem::Dependency
|
90
70
|
name: rubocop-performance
|
91
71
|
requirement: !ruby/object:Gem::Requirement
|
92
72
|
requirements:
|
93
73
|
- - "~>"
|
94
74
|
- !ruby/object:Gem::Version
|
95
|
-
version: '1.
|
75
|
+
version: '1.14'
|
96
76
|
- - ">="
|
97
77
|
- !ruby/object:Gem::Version
|
98
|
-
version: 1.
|
78
|
+
version: 1.14.3
|
99
79
|
type: :development
|
100
80
|
prerelease: false
|
101
81
|
version_requirements: !ruby/object:Gem::Requirement
|
102
82
|
requirements:
|
103
83
|
- - "~>"
|
104
84
|
- !ruby/object:Gem::Version
|
105
|
-
version: '1.
|
85
|
+
version: '1.14'
|
106
86
|
- - ">="
|
107
87
|
- !ruby/object:Gem::Version
|
108
|
-
version: 1.
|
88
|
+
version: 1.14.3
|
109
89
|
- !ruby/object:Gem::Dependency
|
110
90
|
name: rubocop-rails
|
111
91
|
requirement: !ruby/object:Gem::Requirement
|
112
92
|
requirements:
|
113
93
|
- - "~>"
|
114
94
|
- !ruby/object:Gem::Version
|
115
|
-
version: '2.
|
95
|
+
version: '2.15'
|
116
96
|
- - ">="
|
117
97
|
- !ruby/object:Gem::Version
|
118
|
-
version: 2.
|
98
|
+
version: 2.15.2
|
119
99
|
type: :development
|
120
100
|
prerelease: false
|
121
101
|
version_requirements: !ruby/object:Gem::Requirement
|
122
102
|
requirements:
|
123
103
|
- - "~>"
|
124
104
|
- !ruby/object:Gem::Version
|
125
|
-
version: '2.
|
105
|
+
version: '2.15'
|
126
106
|
- - ">="
|
127
107
|
- !ruby/object:Gem::Version
|
128
|
-
version: 2.
|
108
|
+
version: 2.15.2
|
129
109
|
- !ruby/object:Gem::Dependency
|
130
110
|
name: rubocop-rake
|
131
111
|
requirement: !ruby/object:Gem::Requirement
|
132
112
|
requirements:
|
133
113
|
- - "~>"
|
134
114
|
- !ruby/object:Gem::Version
|
135
|
-
version: 0.
|
115
|
+
version: 0.6.0
|
136
116
|
type: :development
|
137
117
|
prerelease: false
|
138
118
|
version_requirements: !ruby/object:Gem::Requirement
|
139
119
|
requirements:
|
140
120
|
- - "~>"
|
141
121
|
- !ruby/object:Gem::Version
|
142
|
-
version: 0.
|
122
|
+
version: 0.6.0
|
143
123
|
- !ruby/object:Gem::Dependency
|
144
124
|
name: rubocop-rspec
|
145
125
|
requirement: !ruby/object:Gem::Requirement
|
146
126
|
requirements:
|
147
|
-
- - ">="
|
148
|
-
- !ruby/object:Gem::Version
|
149
|
-
version: 1.44.1
|
150
127
|
- - "~>"
|
151
128
|
- !ruby/object:Gem::Version
|
152
|
-
version: '2.
|
129
|
+
version: '2.12'
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 2.12.1
|
153
133
|
type: :development
|
154
134
|
prerelease: false
|
155
135
|
version_requirements: !ruby/object:Gem::Requirement
|
156
136
|
requirements:
|
157
|
-
- - ">="
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
version: 1.44.1
|
160
137
|
- - "~>"
|
161
138
|
- !ruby/object:Gem::Version
|
162
|
-
version: '2.
|
139
|
+
version: '2.12'
|
140
|
+
- - ">="
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: 2.12.1
|
163
143
|
- !ruby/object:Gem::Dependency
|
164
144
|
name: simplecov
|
165
145
|
requirement: !ruby/object:Gem::Requirement
|
166
146
|
requirements:
|
167
147
|
- - "~>"
|
168
148
|
- !ruby/object:Gem::Version
|
169
|
-
version: 0.
|
149
|
+
version: 0.22.0
|
170
150
|
type: :development
|
171
151
|
prerelease: false
|
172
152
|
version_requirements: !ruby/object:Gem::Requirement
|
173
153
|
requirements:
|
174
154
|
- - "~>"
|
175
155
|
- !ruby/object:Gem::Version
|
176
|
-
version: 0.
|
156
|
+
version: 0.22.0
|
177
157
|
description: ActiveRecord lookalike but for business model requirements
|
178
158
|
email:
|
179
159
|
- uxman.sherwani@gmail.com
|
@@ -192,6 +172,7 @@ files:
|
|
192
172
|
- lib/service_record/base.rb
|
193
173
|
- lib/service_record/callbacks.rb
|
194
174
|
- lib/service_record/failure.rb
|
175
|
+
- lib/service_record/response.rb
|
195
176
|
- lib/service_record/version.rb
|
196
177
|
homepage: https://github.com/uxxman/service_record
|
197
178
|
licenses:
|
@@ -209,14 +190,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
209
190
|
requirements:
|
210
191
|
- - ">="
|
211
192
|
- !ruby/object:Gem::Version
|
212
|
-
version:
|
193
|
+
version: 3.0.0
|
213
194
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
214
195
|
requirements:
|
215
196
|
- - ">="
|
216
197
|
- !ruby/object:Gem::Version
|
217
198
|
version: '0'
|
218
199
|
requirements: []
|
219
|
-
rubygems_version: 3.
|
200
|
+
rubygems_version: 3.4.10
|
220
201
|
signing_key:
|
221
202
|
specification_version: 4
|
222
203
|
summary: Service objects for rails
|