service_record 1.3.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3af5f714dc3195cb0877476b9d1a7c048549cd9c19ba40ab59a30d67a3d92ff0
4
- data.tar.gz: fc6cf02ec07809395a782754a3416bafcaf26e59c3a8af911233a69958585cf2
3
+ metadata.gz: 66a63b54af431cc368206110f80b04419130698a73a412c0e803d0db5a543ee5
4
+ data.tar.gz: 19553c5c121484b683d076ed2937f6fb97f1e18cdbb6d15e8ce0482be59b0bed
5
5
  SHA512:
6
- metadata.gz: ad3d7ab806691128d9790ea1f4d5e40f47b99435d0b68421b24d7c049af01783d942b2b39a9bf8357116e16d0d1bf728ce69ef73013b32dcc9630e1fe2d7ae54
7
- data.tar.gz: 46d7eecfa6bdfcb4b323ea6f5858c19e56689c160b1ef0265c49ff9633eaf3789a27b7bce1de7b8809127502109e66b95c961ae946f4f4cfc23f132c392d229b
6
+ metadata.gz: 6c7b393c464c97bc71804d69a470d9e3b3a592b6cb68d51f13335075076e76804f68f45f0012846c5c651a56097b89de0924c0d702fddb0377c553c9a901dcce
7
+ data.tar.gz: 4b465a4ebe6db175aebb6ed12900a2468367f82ca4696e7d4daf1c39bf31aa19a63e3394c924da4e6485aa39b519a262947767fec7f2a45361d0c6ac663048c6
data/README.md CHANGED
@@ -1,15 +1,15 @@
1
1
  # ServiceRecord
2
2
 
3
+ [![Gem](https://img.shields.io/gem/v/service_record)](https://rubygems.org/gems/service_record)
3
4
  [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/uxxman/service_record/CI)](https://github.com/uxxman/service_record/actions?query=workflow%3ACI)
4
5
  [![Code Climate coverage](https://img.shields.io/codeclimate/coverage/uxxman/service_record)](https://codeclimate.com/github/uxxman/service_record)
5
6
  [![Code Climate maintainability](https://img.shields.io/codeclimate/maintainability/uxxman/service_record)](https://codeclimate.com/github/uxxman/service_record)
6
- [![Gem](https://img.shields.io/gem/v/service_record)](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' if params[:email].blank?
87
- errors << 'Email is invalid' if params[:email].present? && /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i.match?(params[:email])
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]).try(:authenticate, params[:password])
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
- return JsonWebToken.encode(user_id: user.id) if user.present?
123
-
124
- errors.add :authentication, 'invalid credentials'
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 test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
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
 
@@ -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
- # class MyService < ServiceRecord
11
- # end
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.run_callbacks :perform do
29
- service.result = service.perform
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ServiceRecord
4
- VERSION = '1.3.0'
4
+ VERSION = '1.4.1'
5
5
  end
@@ -1,3 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'service_record/base'
4
+ require 'service_record/version'
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.3.0
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: 2022-01-28 00:00:00.000000000 Z
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.0'
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.0'
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.1
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.1
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.8'
75
+ version: '1.14'
96
76
  - - ">="
97
77
  - !ruby/object:Gem::Version
98
- version: 1.8.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.8'
85
+ version: '1.14'
106
86
  - - ">="
107
87
  - !ruby/object:Gem::Version
108
- version: 1.8.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.8'
95
+ version: '2.15'
116
96
  - - ">="
117
97
  - !ruby/object:Gem::Version
118
- version: 2.8.1
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.8'
105
+ version: '2.15'
126
106
  - - ">="
127
107
  - !ruby/object:Gem::Version
128
- version: 2.8.1
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.5.1
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.5.1
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.0'
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.0'
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.17.1
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.17.1
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: 2.5.0
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.3.3
200
+ rubygems_version: 3.4.10
220
201
  signing_key:
221
202
  specification_version: 4
222
203
  summary: Service objects for rails