service_record 1.3.0 → 1.4.0

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: 761226eff3ab278171ca2a9250b6fe089ceb53eeb2b1e221b680d250c3f1d2be
4
+ data.tar.gz: 567e4aa90fff412e1d42eba985a9e7a3f6397a53d622ec7e996503e22aa78a75
5
5
  SHA512:
6
- metadata.gz: ad3d7ab806691128d9790ea1f4d5e40f47b99435d0b68421b24d7c049af01783d942b2b39a9bf8357116e16d0d1bf728ce69ef73013b32dcc9630e1fe2d7ae54
7
- data.tar.gz: 46d7eecfa6bdfcb4b323ea6f5858c19e56689c160b1ef0265c49ff9633eaf3789a27b7bce1de7b8809127502109e66b95c961ae946f4f4cfc23f132c392d229b
6
+ metadata.gz: 24c06c7384fca171053cd271ef96107ee36753015bd4198ed1b6f87e4ea5fe68db663d4a7a9e7b50af6cd8a03d71bce575ff3e17d8ffba2045442b55e8dafb19
7
+ data.tar.gz: 2889e28b5f8507849beaef07ce99fd886063a4cf40c91d035ad92190788d8322d956e0315aa94a85a067471671a36d634171e84a26d56c65692fd651c0b998de
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,9 @@ 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
+
179
+ ServiceRecord uses appraisals to test the code base against multiple versions of Rails ActiveModel. When first developing, you need to run `bundle install` and then `bundle exec appraisal install`, to install the different gem sets. You can then run all appraisal files (like CI does), with `appraisal rake`.
178
180
 
179
181
  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
182
 
@@ -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.0'
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.0
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: 2022-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '2.3'
33
+ version: '2.4'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '2.3'
40
+ version: '2.4'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -45,9 +45,6 @@ dependencies:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '13.0'
48
- - - ">="
49
- - !ruby/object:Gem::Version
50
- version: 13.0.1
51
48
  type: :development
52
49
  prerelease: false
53
50
  version_requirements: !ruby/object:Gem::Requirement
@@ -55,9 +52,6 @@ dependencies:
55
52
  - - "~>"
56
53
  - !ruby/object:Gem::Version
57
54
  version: '13.0'
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- version: 13.0.1
61
55
  - !ruby/object:Gem::Dependency
62
56
  name: rspec
63
57
  requirement: !ruby/object:Gem::Requirement
@@ -78,88 +72,88 @@ dependencies:
78
72
  requirements:
79
73
  - - "~>"
80
74
  - !ruby/object:Gem::Version
81
- version: 0.5.1
75
+ version: 0.5.2
82
76
  type: :development
83
77
  prerelease: false
84
78
  version_requirements: !ruby/object:Gem::Requirement
85
79
  requirements:
86
80
  - - "~>"
87
81
  - !ruby/object:Gem::Version
88
- version: 0.5.1
82
+ version: 0.5.2
89
83
  - !ruby/object:Gem::Dependency
90
84
  name: rubocop-performance
91
85
  requirement: !ruby/object:Gem::Requirement
92
86
  requirements:
93
87
  - - "~>"
94
88
  - !ruby/object:Gem::Version
95
- version: '1.8'
89
+ version: '1.14'
96
90
  - - ">="
97
91
  - !ruby/object:Gem::Version
98
- version: 1.8.1
92
+ version: 1.14.3
99
93
  type: :development
100
94
  prerelease: false
101
95
  version_requirements: !ruby/object:Gem::Requirement
102
96
  requirements:
103
97
  - - "~>"
104
98
  - !ruby/object:Gem::Version
105
- version: '1.8'
99
+ version: '1.14'
106
100
  - - ">="
107
101
  - !ruby/object:Gem::Version
108
- version: 1.8.1
102
+ version: 1.14.3
109
103
  - !ruby/object:Gem::Dependency
110
104
  name: rubocop-rails
111
105
  requirement: !ruby/object:Gem::Requirement
112
106
  requirements:
113
107
  - - "~>"
114
108
  - !ruby/object:Gem::Version
115
- version: '2.8'
109
+ version: '2.15'
116
110
  - - ">="
117
111
  - !ruby/object:Gem::Version
118
- version: 2.8.1
112
+ version: 2.15.2
119
113
  type: :development
120
114
  prerelease: false
121
115
  version_requirements: !ruby/object:Gem::Requirement
122
116
  requirements:
123
117
  - - "~>"
124
118
  - !ruby/object:Gem::Version
125
- version: '2.8'
119
+ version: '2.15'
126
120
  - - ">="
127
121
  - !ruby/object:Gem::Version
128
- version: 2.8.1
122
+ version: 2.15.2
129
123
  - !ruby/object:Gem::Dependency
130
124
  name: rubocop-rake
131
125
  requirement: !ruby/object:Gem::Requirement
132
126
  requirements:
133
127
  - - "~>"
134
128
  - !ruby/object:Gem::Version
135
- version: 0.5.1
129
+ version: 0.6.0
136
130
  type: :development
137
131
  prerelease: false
138
132
  version_requirements: !ruby/object:Gem::Requirement
139
133
  requirements:
140
134
  - - "~>"
141
135
  - !ruby/object:Gem::Version
142
- version: 0.5.1
136
+ version: 0.6.0
143
137
  - !ruby/object:Gem::Dependency
144
138
  name: rubocop-rspec
145
139
  requirement: !ruby/object:Gem::Requirement
146
140
  requirements:
147
- - - ">="
148
- - !ruby/object:Gem::Version
149
- version: 1.44.1
150
141
  - - "~>"
151
142
  - !ruby/object:Gem::Version
152
- version: '2.0'
143
+ version: '2.12'
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: 2.12.1
153
147
  type: :development
154
148
  prerelease: false
155
149
  version_requirements: !ruby/object:Gem::Requirement
156
150
  requirements:
157
- - - ">="
158
- - !ruby/object:Gem::Version
159
- version: 1.44.1
160
151
  - - "~>"
161
152
  - !ruby/object:Gem::Version
162
- version: '2.0'
153
+ version: '2.12'
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ version: 2.12.1
163
157
  - !ruby/object:Gem::Dependency
164
158
  name: simplecov
165
159
  requirement: !ruby/object:Gem::Requirement
@@ -192,6 +186,7 @@ files:
192
186
  - lib/service_record/base.rb
193
187
  - lib/service_record/callbacks.rb
194
188
  - lib/service_record/failure.rb
189
+ - lib/service_record/response.rb
195
190
  - lib/service_record/version.rb
196
191
  homepage: https://github.com/uxxman/service_record
197
192
  licenses:
@@ -209,14 +204,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
209
204
  requirements:
210
205
  - - ">="
211
206
  - !ruby/object:Gem::Version
212
- version: 2.5.0
207
+ version: 2.7.5
213
208
  required_rubygems_version: !ruby/object:Gem::Requirement
214
209
  requirements:
215
210
  - - ">="
216
211
  - !ruby/object:Gem::Version
217
212
  version: '0'
218
213
  requirements: []
219
- rubygems_version: 3.3.3
214
+ rubygems_version: 3.3.7
220
215
  signing_key:
221
216
  specification_version: 4
222
217
  summary: Service objects for rails