service_record 1.0.0 → 1.2.4

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: 904da829c98aa5d247c5979f1a01d4a23214e96cb24855bd3ca501275f28dbec
4
- data.tar.gz: 1b5443f94ceab5481cbf3afcb08180ca3af00de5ab4e9ec04e315bb431f9c3ef
3
+ metadata.gz: b7916d1e6a73deee6ce9dddf92550452365db224960d08d4171db0581bc67fde
4
+ data.tar.gz: 57d614b6361e6643890c88730100fe33b490c109962d66e4dae241a985bf9e42
5
5
  SHA512:
6
- metadata.gz: 02bebf02ace3c9af193819c7ff4ce0cd33427ef6f7e91b8911a0f6c3ceb2a547c0f4dbd301409652dc0f199e1ca5de304b8e2732c8516d655f11fb7597504961
7
- data.tar.gz: cd925c97f73d12b5af2ca54351b93ee64654e5065c7e9363281f5542976941ccf99f73dbd474d77b834c8b622e0c4d737e373c221064803cdf01a959b24c2401
6
+ metadata.gz: 4e4807fa30e0d3b053dd769078c8d3938eb02ad7de3f14812fa3bf9a6442f38652a317bff66ac4765c273b1b29c24697ae71cc857040263de03df4361869f4cd
7
+ data.tar.gz: '0488df45e2d0177e24db8f1f88077ccc94b1e8c91e7612a6176ad70f99802561fe0f774e61a73eaccaf0a0c1ce9cfaf4b6223a0cbe1a4743877305e389924e8f'
data/README.md CHANGED
@@ -1,8 +1,13 @@
1
1
  # ServiceRecord
2
2
 
3
+ [![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
+ [![Code Climate coverage](https://img.shields.io/codeclimate/coverage/uxxman/service_record)](https://codeclimate.com/github/uxxman/service_record)
5
+ [![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
+
3
8
  An ActiveRecord lookalike but for business model requirements, a.k.a Service Objects.
4
9
 
5
- Rails is packed with all the amazing tools to get you started with building your new awesome project and enforces reliable and battle-tested guidelines. One of the 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.
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.
6
11
 
7
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.
8
13
 
@@ -59,7 +64,9 @@ The returned response from a service will have the following useful attributes/m
59
64
  * `success?` contains true if service was performed without any errors, false otherwise
60
65
  * `failure?` contains opposite of success?
61
66
  * `result` contains returned value of service perform function
62
- * `errors` contains details about issues that occurr while performing the service
67
+ * `errors` contains details about issues that occurr while performing the service
68
+
69
+ There is a **perform!** (with a bang !) method which will raise **ServiceRecord::Failure** in case of service failure.
63
70
 
64
71
 
65
72
 
@@ -133,14 +140,12 @@ end
133
140
 
134
141
  ## Validations
135
142
 
136
- ServiceRecord extends on `ActiveModel::Validations`, so, everything that you can do there can be done inside a service class and ServiceRecord will make sure that a service only runs the perform function when all validations are passed, otherwise `errors` will contain details about the validation issues. Since services don't have an underlining object that needs to persisted like in ActiveRecord, you should avoid conditons filters like on create/update/save etc.
137
-
138
- You can also define callbacks like `before_validation` and `after_validation` just like you do inside an ActiveRecord class.
143
+ ServiceRecord extends on `ActiveModel::Validations`, so, everything that you can do there can be done inside a service class and ServiceRecord will make sure that a service only runs the perform function when all validations are passed, otherwise `errors` will contain details about the validation issues.
139
144
 
140
145
 
141
146
  ## Custom Errors
142
147
 
143
- Just like validation errors, you can also add custom errors that you want to be reported. It useful to handle errors which are not related to input parameters validation. E.g.
148
+ Just like validation errors, you can also add custom errors that you want to be reported. Use them to handle errors which are not related to input parameters validation. E.g.
144
149
 
145
150
  ```ruby
146
151
  errors.add :authentication, 'invalid credentials'
@@ -158,12 +163,13 @@ class SampleService < ApplicationService
158
163
  end
159
164
 
160
165
  private
161
- def do_something
162
- end
166
+
167
+ def do_something
168
+ end
163
169
  end
164
170
  ```
165
171
 
166
- Availble callbacks are `before_perform`, `after_perform` and `around_perform`. If a `before_perform` calls `throw :abort`, the callback chain is hallted and perform function would not be called.
172
+ Availble callbacks are `before_perform`, `after_perform` and `around_perform`. If a `before_perform` calls `throw :abort`, the callback chain is hallted and perform function will not be called.
167
173
 
168
174
 
169
175
  ## Development
@@ -174,7 +180,13 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
174
180
 
175
181
  ## Contributing
176
182
 
177
- Bug reports and pull requests are welcome on GitHub at https://github.com/uxxman-sherwani/service_record.
183
+ 1. Fork it
184
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
185
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
186
+ 4. Push to the branch (`git push origin my-new-feature`)
187
+ 5. Create new Pull Request
188
+
189
+ Bug reports and pull requests are welcome on GitHub at https://github.com/uxxman/service_record.
178
190
 
179
191
 
180
192
  ## License
@@ -1,3 +1,2 @@
1
1
  require 'active_model'
2
2
  require 'service_record/base'
3
- require 'service_record/version'
@@ -1,3 +1,4 @@
1
+ require 'service_record/failure'
1
2
  require 'service_record/callbacks'
2
3
 
3
4
  module ServiceRecord
@@ -6,21 +7,26 @@ module ServiceRecord
6
7
  include ActiveModel::Attributes
7
8
  include ActiveModel::Validations
8
9
  include ActiveModel::AttributeAssignment
9
- include ActiveModel::Validations::Callbacks
10
10
 
11
11
  def self.perform(args = {})
12
12
  new.tap do |service|
13
13
  service.attributes = args
14
+ break service unless service.valid?
14
15
 
15
- if service.valid?
16
- service.run_callbacks :perform do
17
- service.result = service.perform
18
- service.result = nil if service.failure?
19
- end
16
+ service.run_callbacks :perform do
17
+ service.result = service.perform
18
+ service.result = nil if service.failure?
20
19
  end
21
20
  end
22
21
  end
23
22
 
23
+ def self.perform!(args = {})
24
+ service = perform(args)
25
+ return service if service.success?
26
+
27
+ raise Failure, service
28
+ end
29
+
24
30
  attr_accessor :result
25
31
 
26
32
  def success?
@@ -5,7 +5,7 @@ module ServiceRecord
5
5
  included do
6
6
  include ActiveSupport::Callbacks
7
7
 
8
- define_callbacks :perform
8
+ define_callbacks :perform, skip_after_callbacks_if_terminated: true
9
9
  end
10
10
 
11
11
  class_methods do
@@ -0,0 +1,11 @@
1
+ module ServiceRecord
2
+ class Failure < StandardError
3
+ attr_reader :service
4
+
5
+ def initialize(service)
6
+ @service = service
7
+
8
+ super(@service.errors.full_messages.join(','))
9
+ end
10
+ end
11
+ end
@@ -1,3 +1,3 @@
1
1
  module ServiceRecord
2
- VERSION = '1.0.0'
2
+ VERSION = '1.2.4'.freeze
3
3
  end
metadata CHANGED
@@ -1,61 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: service_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muhammad Usman
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-04-17 00:00:00.000000000 Z
11
+ date: 2020-10-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '6.0'
19
+ version: '5.0'
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'
26
+ version: '5.0'
27
27
  description: ActiveRecord lookalike but for business model requirements
28
28
  email:
29
29
  - uxman.sherwani@gmail.com
30
30
  executables: []
31
31
  extensions: []
32
- extra_rdoc_files: []
32
+ extra_rdoc_files:
33
+ - README.md
34
+ - LICENSE.txt
33
35
  files:
34
- - ".gitignore"
35
- - ".rspec"
36
- - ".travis.yml"
37
- - Gemfile
38
- - Gemfile.lock
39
36
  - LICENSE.txt
40
37
  - README.md
41
- - Rakefile
42
- - bin/console
43
- - bin/setup
44
38
  - lib/rails/generators/service/service_generator.rb
45
39
  - lib/rails/generators/service/templates/application_service.rb.tt
46
40
  - lib/rails/generators/service/templates/service.rb.tt
47
41
  - lib/service_record.rb
48
42
  - lib/service_record/base.rb
49
43
  - lib/service_record/callbacks.rb
44
+ - lib/service_record/failure.rb
50
45
  - lib/service_record/version.rb
51
- - service_record.gemspec
52
46
  homepage: https://github.com/uxxman/service_record
53
47
  licenses:
54
48
  - MIT
55
49
  metadata:
56
50
  homepage_uri: https://github.com/uxxman/service_record
57
51
  source_code_uri: https://github.com/uxxman/service_record
58
- changelog_uri: https://github.com/uxxman/service_record
52
+ changelog_uri: https://github.com/uxxman/service_record/releases
59
53
  post_install_message:
60
54
  rdoc_options: []
61
55
  require_paths:
data/.gitignore DELETED
@@ -1,11 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
-
10
- # rspec failure tracking
11
- .rspec_status
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
@@ -1,6 +0,0 @@
1
- ---
2
- language: ruby
3
- cache: bundler
4
- rvm:
5
- - 2.7.0
6
- before_install: gem install bundler -v 2.1.4
data/Gemfile DELETED
@@ -1,7 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in service_record.gemspec
4
- gemspec
5
-
6
- gem 'rake', '~> 12.3'
7
- gem 'rspec', '~> 3.9'
@@ -1,51 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- service_record (1.0.0)
5
- activemodel (~> 6.0)
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- activemodel (6.0.2.2)
11
- activesupport (= 6.0.2.2)
12
- activesupport (6.0.2.2)
13
- concurrent-ruby (~> 1.0, >= 1.0.2)
14
- i18n (>= 0.7, < 2)
15
- minitest (~> 5.1)
16
- tzinfo (~> 1.1)
17
- zeitwerk (~> 2.2)
18
- concurrent-ruby (1.1.6)
19
- diff-lcs (1.3)
20
- i18n (1.8.2)
21
- concurrent-ruby (~> 1.0)
22
- minitest (5.14.0)
23
- rake (12.3.3)
24
- rspec (3.9.0)
25
- rspec-core (~> 3.9.0)
26
- rspec-expectations (~> 3.9.0)
27
- rspec-mocks (~> 3.9.0)
28
- rspec-core (3.9.1)
29
- rspec-support (~> 3.9.1)
30
- rspec-expectations (3.9.1)
31
- diff-lcs (>= 1.2.0, < 2.0)
32
- rspec-support (~> 3.9.0)
33
- rspec-mocks (3.9.1)
34
- diff-lcs (>= 1.2.0, < 2.0)
35
- rspec-support (~> 3.9.0)
36
- rspec-support (3.9.2)
37
- thread_safe (0.3.6)
38
- tzinfo (1.2.6)
39
- thread_safe (~> 0.1)
40
- zeitwerk (2.3.0)
41
-
42
- PLATFORMS
43
- ruby
44
-
45
- DEPENDENCIES
46
- rake (~> 12.3)
47
- rspec (~> 3.9)
48
- service_record!
49
-
50
- BUNDLED WITH
51
- 2.1.4
data/Rakefile DELETED
@@ -1,6 +0,0 @@
1
- require 'bundler/gem_tasks'
2
- require 'rspec/core/rake_task'
3
-
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
- task default: :spec
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "service_record"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
@@ -1,30 +0,0 @@
1
- require_relative 'lib/service_record/version'
2
-
3
- Gem::Specification.new do |spec|
4
- spec.name = 'service_record'
5
- spec.version = ServiceRecord::VERSION
6
- spec.authors = ['Muhammad Usman']
7
- spec.email = ['uxman.sherwani@gmail.com']
8
-
9
- spec.summary = 'Service objects for rails'
10
- spec.description = 'ActiveRecord lookalike but for business model requirements'
11
- spec.homepage = 'https://github.com/uxxman/service_record'
12
- spec.license = 'MIT'
13
- spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
14
-
15
- spec.metadata['homepage_uri'] = spec.homepage
16
- spec.metadata['source_code_uri'] = spec.homepage
17
- spec.metadata['changelog_uri'] = spec.homepage
18
-
19
- # Specify which files should be added to the gem when it is released.
20
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
21
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
22
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
23
- end
24
-
25
- spec.bindir = 'exe'
26
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
- spec.require_paths = ['lib']
28
-
29
- spec.add_dependency 'activemodel', '~> 6.0'
30
- end