solidservice 0.1.0 → 1.0.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: 7141572a223276cd54f17af3fec910c9ca9f064c4d70beaee5f85c10defe88cb
4
- data.tar.gz: e07fda6b224cac244fb85f44fbf5d10468323a27e0ebf2ffcf5dd4c4b40e31ed
3
+ metadata.gz: 4f392725c3e702c59ac368f8b437d4e16a4485f7326b35b818d38cc1225e8098
4
+ data.tar.gz: d26bab0fb422776548372ed8da261ac18ad0f0040a3d520d48f80bea6866b1fb
5
5
  SHA512:
6
- metadata.gz: 372fefa3c563a54bfbe246142f873dbecab933434ac838e0ac28d1d415226ded0826b34b6572e3ec793a94223489b5d0fe77cdbcaf7e6c5aff2f4094053f17ce
7
- data.tar.gz: 4fd9dfe75a6d5d14abb9561d8fa62091b2cd4f92dd3f8e50b9485601f54280cb7d34e50e75260fb1e4ca9f901eaa1225cb8a9c8f6627085470095cc3493bffee
6
+ metadata.gz: 237fc7a04efec213147e501c52fbcd71b1d26463d75ffceb1e63f0317acd65f45876265726880a99bd3ce9862c1ac68602be12d4e0b51aa8ed44084e9b031dda
7
+ data.tar.gz: 836fe0f7b0026cee670295d3f911a3c6bdfc0ab1a26c1bc20cd0f421324233e67301021319265fcbcefb2aa5c0049f87e024ec4be4e32ba0a95c827d3fd529c7
data/Gemfile CHANGED
@@ -2,9 +2,19 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ if rails_version = ENV['RAILS_VERSION']
6
+ gem 'rails', rails_version
7
+ end
8
+
5
9
  # Specify your gem's dependencies in solidservice.gemspec
6
10
  gemspec
7
11
 
8
12
  gem "rake", "~> 13.0"
9
13
 
10
14
  gem "minitest", "~> 5.0"
15
+
16
+ group :development, :test do
17
+ gem "debug"
18
+ gem 'matrixeval-ruby'
19
+ gem 'simplecov'
20
+ end
data/README.md CHANGED
@@ -1,32 +1,170 @@
1
1
  # SolidService
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/solidservice`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ [![CI](https://github.com/hoppergee/solidservice/actions/workflows/main.yml/badge.svg)](https://github.com/hoppergee/solidservice/actions/workflows/main.yml)
4
+ [![Maintainability](https://api.codeclimate.com/v1/badges/625ef769e60ab39159ce/maintainability)](https://codeclimate.com/github/hoppergee/solidservice/maintainability)
5
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/625ef769e60ab39159ce/test_coverage)](https://codeclimate.com/github/hoppergee/solidservice/test_coverage)
4
6
 
5
- TODO: Delete this and the text above, and describe your gem
7
+ Servcie object with a simple API.
8
+
9
+ ```ruby
10
+ result = ASolidService.call(any: 'thing', you: 'like')
11
+ result.success? #=> true
12
+ result.fail? #=> false
13
+ ```
14
+
15
+ - One service per action
16
+ - Service only has one public method `.call` with a hash input argument
17
+ - The `.call` always return a `State` object. You can ask the state object the execution result
6
18
 
7
19
  ## Installation
8
20
 
9
21
  Install the gem and add to the application's Gemfile by executing:
10
22
 
11
- $ bundle add solidservice
23
+ ```bash
24
+ $ bundle add solidservice
25
+ ```
12
26
 
13
- If bundler is not being used to manage dependencies, install the gem by executing:
27
+ Or manually add it in Gemfile
14
28
 
15
- $ gem install solidservice
29
+ ```ruby
30
+ gem 'solidservice'
31
+ ```
16
32
 
17
- ## Usage
18
33
 
19
- TODO: Write usage instructions here
34
+ ## Basic Usage
20
35
 
21
- ## Development
36
+ Here is an example for Rails app.
37
+
38
+ 1. Create a `services` folder
39
+
40
+ ```bash
41
+ mkdir app/services
42
+ ```
43
+
44
+ 2. Create the service you want
45
+
46
+ ```ruby
47
+ class UpdateUser < SolidService
48
+ def call
49
+ if user.update(user_params)
50
+ success!(user: user)
51
+ else
52
+ fail!(user: user)
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def user
59
+ @user ||= User.find(params[:id])
60
+ end
61
+
62
+ def user_params
63
+ @user ||= params[:user_params]
64
+ end
65
+ end
66
+ ```
67
+
68
+ 3. Use this service in controller
69
+
70
+ ```ruby
71
+ class UsersController < ApplicationController
72
+ def update
73
+ result = UpdateUser.call(
74
+ id: params[:id],
75
+ user_params: params.require(:user).permit(:email)
76
+ )
77
+
78
+ if result.success?
79
+ redirect_to root_path
80
+ else
81
+ @user = result.user
82
+ render :edit
83
+ end
84
+ end
85
+ end
86
+ ```
87
+
88
+ ## Only 4 DSL in the `call` method
89
+
90
+ - `success!` - Success the servcie immediately, any code after it won't be execute (Recommend)
91
+ - `success` - Just update the state to success
92
+ - `fail!` - Fail the service immediately, any code after it won't be execute (Recommend)
93
+ - `fail` - Just update the state to fail
22
94
 
23
- 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.
95
+ ## How to return other data
96
+
97
+ You can send data with state object like this:
98
+
99
+ ```ruby
100
+ success!(user: user)
101
+ success(user: user, item: item)
102
+ fail!(email: email, error: error)
103
+ fail(error: error)
104
+ ```
105
+
106
+ Then we can get those data on the result:
107
+
108
+ ```ruby
109
+ result = ExampleService.call
110
+ result.success? #=> true
111
+ result.user
112
+ result.item
113
+
114
+ result.success? #=> false
115
+ result.error
116
+ result.email
117
+ ```
118
+
119
+ ## Servcie success by default
120
+
121
+ If you don't call above 4 methods, the servcie will be marked as success by default. It's some those service which just want to execute some action and don't want to return any thing.
122
+
123
+ ```ruby
124
+ class ACommandService < SolidService
125
+ def call
126
+ # Do some actions that don't need to return anything
127
+ end
128
+ end
129
+
130
+ result = ACommandService.call
131
+ result.success? #=> true
132
+ ```
133
+
134
+ ## Use service in service with `call!`
135
+
136
+ Sometimes, we want to use a service in another service, but don't want to doing `if/else` on the state object everywhere, then we can use `call!` for the inner service. Then the service will raise error on failure.
137
+
138
+ ```ruby
139
+ class Action2 < SolidService
140
+ def call
141
+ fail!(error: StandardError.new('something wrong'))
142
+ end
143
+ end
144
+
145
+ class Action1 < SolidService
146
+ def call
147
+ Action2.call!
148
+ end
149
+ end
150
+
151
+ result = Action1.call
152
+ result.fail? #=> true
153
+ result.error #=> #<StandardError: something wrong>
154
+ ```
155
+
156
+
157
+ ## Development
24
158
 
25
- 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 the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
159
+ ```bash
160
+ bundle install
161
+ meval rake # Run test
162
+ meval -a rake # Run tests against all Ruby versions and Rails versions
163
+ ```
26
164
 
27
165
  ## Contributing
28
166
 
29
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/solidservice. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/solidservice/blob/master/CODE_OF_CONDUCT.md).
167
+ Bug reports and pull requests are welcome on GitHub at https://github.com/hoppergee/solidservice. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/hoppergee/solidservice/blob/master/CODE_OF_CONDUCT.md).
30
168
 
31
169
  ## License
32
170
 
@@ -34,4 +172,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
34
172
 
35
173
  ## Code of Conduct
36
174
 
37
- Everyone interacting in the SolidService project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/solidservice/blob/master/CODE_OF_CONDUCT.md).
175
+ Everyone interacting in the SolidService project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/hoppergee/solidservice/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,69 @@
1
+ module SolidService
2
+ class Base
3
+
4
+ class << self
5
+
6
+ def call(params={})
7
+ service = new(params)
8
+ service.call
9
+ service.state
10
+
11
+ rescue Success
12
+ service.state
13
+
14
+ rescue Failure
15
+ service.state
16
+
17
+ rescue => e
18
+ service.fail(error: e)
19
+ service.state
20
+ end
21
+
22
+ def call!(params={})
23
+ state = call(params)
24
+ return state unless state.fail?
25
+
26
+ if state.error
27
+ raise state.error
28
+ else
29
+ raise Error.new("Service failed", service_result: state)
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+ attr_reader :params, :state
36
+
37
+ def initialize(params)
38
+ @params = (params || {}).with_indifferent_access
39
+ @state = State.new(:success)
40
+ end
41
+
42
+ def call
43
+ raise "Override please"
44
+ end
45
+
46
+ ##########
47
+ # Private
48
+ ##########
49
+
50
+ def success!(params={})
51
+ @state = State.new(:success, params)
52
+ raise Success.new
53
+ end
54
+
55
+ def fail!(params={})
56
+ @state = State.new(:fail, params)
57
+ raise Failure.new
58
+ end
59
+
60
+ def success(params={})
61
+ @state = State.new(:success, params)
62
+ end
63
+
64
+ def fail(params={})
65
+ @state = State.new(:fail, params)
66
+ end
67
+
68
+ end
69
+ end
@@ -0,0 +1,10 @@
1
+ module SolidService
2
+ class Error < StandardError
3
+ attr_reader :service_result
4
+
5
+ def initialize(message, params={})
6
+ @service_result = params[:service_result]
7
+ super(message)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,4 @@
1
+ module SolidService
2
+ class Failure < StandardError
3
+ end
4
+ end
@@ -0,0 +1,20 @@
1
+ module SolidService
2
+ class State
3
+ def initialize(state = :success, data={})
4
+ @state = state || :success
5
+ @_data = (data || {}).with_indifferent_access
6
+ end
7
+
8
+ def success?
9
+ @state == :success
10
+ end
11
+
12
+ def fail?
13
+ @state == :fail
14
+ end
15
+
16
+ def method_missing(key)
17
+ @_data[key]
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,4 @@
1
+ module SolidService
2
+ class Success < StandardError
3
+ end
4
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SolidService
4
- VERSION = "0.1.0"
4
+ VERSION = "1.0.0"
5
5
  end
data/lib/solidservice.rb CHANGED
@@ -1,8 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "solidservice/version"
4
+ require "active_support/core_ext/hash/indifferent_access"
4
5
 
5
6
  module SolidService
6
- class Error < StandardError; end
7
- # Your code goes here...
7
+ autoload :Error, "solidservice/error"
8
+ autoload :Failure, "solidservice/failure"
9
+ autoload :Success, "solidservice/success"
10
+
11
+ autoload :State, "solidservice/state"
12
+
13
+ autoload :Base, "solidservice/base"
8
14
  end
data/matrixeval.yml ADDED
@@ -0,0 +1,77 @@
1
+ version: 0.4
2
+ target: ruby
3
+ project_name: solidservice
4
+ parallel_workers: number_of_processors
5
+ commands:
6
+ # - ps
7
+ # - top
8
+ # - an_additional_command
9
+ # mounts:
10
+ # - /a/path/need/to/mount:/a/path/mount/to
11
+ matrix:
12
+ ruby:
13
+ main: true
14
+ variants:
15
+ - key: 2.6
16
+ container:
17
+ image: ruby:2.6.10
18
+ - key: 2.7
19
+ container:
20
+ image: ruby:2.7.6
21
+ - key: 3.0
22
+ container:
23
+ image: ruby:3.0.4
24
+ - key: 3.1
25
+ default: true
26
+ container:
27
+ image: ruby:3.1.2
28
+ # - key: jruby-9.3
29
+ # container:
30
+ # image: jruby:9.3
31
+ # env:
32
+ # PATH: "/opt/jruby/bin:/app/bin:/bundle/bin:$PATH"
33
+ # mounts:
34
+ # - /a/path/need/to/mount:/a/path/mount/to
35
+
36
+ rails:
37
+ variants:
38
+ - key: 6.0
39
+ env:
40
+ RAILS_VERSION: "~> 6.0.0"
41
+ - key: 6.1
42
+ env:
43
+ RAILS_VERSION: "~> 6.1.0"
44
+ - key: 7.0
45
+ default: true
46
+ env:
47
+ RAILS_VERSION: "~> 7.0.0"
48
+ # another:
49
+ # variants:
50
+ # - key: key1
51
+ # default: true
52
+ # env:
53
+ # ENV_KEY: 1
54
+ # - key: key2
55
+ # env:
56
+ # ENV_KEY: 2
57
+
58
+ exclude:
59
+ - ruby: 2.6
60
+ rails: 7.0
61
+ # - ruby: jruby-9.3
62
+ # rails: 7.0
63
+
64
+ docker-compose-extend:
65
+ # services:
66
+ # postgres:
67
+ # image: postgres:12.8
68
+ # volumes:
69
+ # - postgres12:/var/lib/postgresql/data
70
+ # environment:
71
+ # POSTGRES_HOST_AUTH_METHOD: trust
72
+
73
+ # redis:
74
+ # image: redis:6.2-alpine
75
+
76
+ # volumes:
77
+ # postgres12:
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solidservice
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hopper Gee
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-04-30 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2022-05-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">"
18
+ - !ruby/object:Gem::Version
19
+ version: '5'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">"
25
+ - !ruby/object:Gem::Version
26
+ version: '5'
13
27
  description: Service object with a simple API
14
28
  email:
15
29
  - hopper.gee@hey.com
@@ -24,7 +38,13 @@ files:
24
38
  - README.md
25
39
  - Rakefile
26
40
  - lib/solidservice.rb
41
+ - lib/solidservice/base.rb
42
+ - lib/solidservice/error.rb
43
+ - lib/solidservice/failure.rb
44
+ - lib/solidservice/state.rb
45
+ - lib/solidservice/success.rb
27
46
  - lib/solidservice/version.rb
47
+ - matrixeval.yml
28
48
  homepage: https://github.com/hoppergee/solidservice
29
49
  licenses:
30
50
  - MIT