services 2.2.6 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +7 -7
- data/lib/services.rb +2 -0
- data/lib/services/base.rb +2 -6
- data/lib/services/modules/object_class.rb +9 -0
- data/lib/services/{base_finder.rb → query.rb} +10 -3
- data/lib/services/railtie.rb +4 -4
- data/lib/services/version.rb +1 -1
- data/spec/services/{base_finder_spec.rb → query_spec.rb} +2 -2
- data/spec/support/test_services.rb +2 -2
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d53cbcc74506968392685a47758d817de8567d05
|
4
|
+
data.tar.gz: 40e349518171bac33c11e2ff5ade10e823236c21
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2c5f4c9db7cac2dea8ffc1ddfd202cd35a67fea3e5f21185a303a862cc30013ba962a8659fa2850a964497268b1c4a355b339b05243c60153b4ec0f298d6de0
|
7
|
+
data.tar.gz: d822b34fe0db413a3b310bd4560cc7d14bd0d6f6da92693cc2cb007e2335103fa7754be76efd9d26eebd09c7fa94a40aa3d3183087890b1bf2a5bb4134bbfa55
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -33,7 +33,7 @@ To process services in the background, Services uses [Sidekiq](https://github.co
|
|
33
33
|
|
34
34
|
#### Postgres
|
35
35
|
|
36
|
-
The SQL that `Services::
|
36
|
+
The SQL that `Services::Query` (discussed further down) generates is optimized for Postgres. It might work with other databases but it's not guaranteed. If you're not using Postgres, don't use `Services::Query` or, even better, submit a [pull request](https://github.com/krautcomputing/services/issues) that fixes it to work with your database!
|
37
37
|
|
38
38
|
### Basic principles
|
39
39
|
|
@@ -54,7 +54,7 @@ Apart from these basic principles, you can implement the actual logic in a servi
|
|
54
54
|
|
55
55
|
Follow these conventions when using Services in your Rails app:
|
56
56
|
|
57
|
-
* services inherit from `Services::Base` (or `Services::
|
57
|
+
* services inherit from `Services::Base` (or `Services::Query`)
|
58
58
|
* services are located in `app/services/`
|
59
59
|
* services are namespaced with the model they operate on and their names are verbs, e.g. `app/services/users/delete.rb` defines `Services::Users::Delete`. If a service operates on multiple models or no models at all, don't namespace them (`Services::DoStuff`) or namespace them by logical groups unrelated to models (`Services::Maintenance::CleanOldUsers`, `Services::Maintenance::SendDailySummary`, etc.)
|
60
60
|
* some services call other services. Try to not combine multiple calls to other services and business logic in one service. Instead, some services should contain only business logic and other services only a bunch of service calls but no (or little) business logic. This keeps your services nice and modular.
|
@@ -121,12 +121,12 @@ As you can see, the helper `find_objects` is used to make sure you are dealing w
|
|
121
121
|
|
122
122
|
It's good practice to always return the objects a service has been operating on at the end of the service.
|
123
123
|
|
124
|
-
Another example, this time using `Services::
|
124
|
+
Another example, this time using `Services::Query`:
|
125
125
|
|
126
126
|
```ruby
|
127
127
|
module Services
|
128
128
|
module Users
|
129
|
-
class Find < Services::
|
129
|
+
class Find < Services::Query
|
130
130
|
private def process(scope, conditions)
|
131
131
|
conditions.each do |k, v|
|
132
132
|
case k
|
@@ -147,11 +147,11 @@ module Services
|
|
147
147
|
end
|
148
148
|
```
|
149
149
|
|
150
|
-
Since you will create services to find objects for pretty much every model you have and they all look very similar, i.e. process the find conditions and return a `ActiveRecord::Relation`, you can let those services inherit from `Services::
|
150
|
+
Since you will create services to find objects for pretty much every model you have and they all look very similar, i.e. process the find conditions and return a `ActiveRecord::Relation`, you can let those services inherit from `Services::Query` to remove some of the boilerplate.
|
151
151
|
|
152
|
-
`Services::
|
152
|
+
`Services::Query` inherits from `Services::Base` and takes an array of IDs and a hash of conditions as parameters. It then extracts some special conditions (:order, :limit, :page, :per_page) that are handled separately and passes a `ActiveRecord::Relation` and the remaining conditions to the `process` method that the inheriting class must define. This method should handle all the conditions, extend the scope and return it.
|
153
153
|
|
154
|
-
Check out [the source of `Services::
|
154
|
+
Check out [the source of `Services::Query`](lib/services/base_finder.rb) to understand what it does in more detail.
|
155
155
|
|
156
156
|
### Helpers
|
157
157
|
|
data/lib/services.rb
CHANGED
@@ -21,6 +21,8 @@ rescue Services::BackgroundProcessorNotFound
|
|
21
21
|
end
|
22
22
|
require_relative 'services/modules/call_logger'
|
23
23
|
require_relative 'services/modules/exception_wrapper'
|
24
|
+
require_relative 'services/modules/object_class'
|
24
25
|
require_relative 'services/modules/uniqueness_checker'
|
25
26
|
require_relative 'services/base'
|
27
|
+
require_relative 'services/query'
|
26
28
|
require_relative 'services/railtie' if defined?(Rails)
|
data/lib/services/base.rb
CHANGED
@@ -4,6 +4,8 @@ require 'digest'
|
|
4
4
|
|
5
5
|
module Services
|
6
6
|
class Base
|
7
|
+
include ObjectClass
|
8
|
+
|
7
9
|
class << self
|
8
10
|
def inherited(subclass)
|
9
11
|
subclass.const_set :Error, Class.new(StandardError)
|
@@ -65,12 +67,6 @@ module Services
|
|
65
67
|
end
|
66
68
|
end
|
67
69
|
|
68
|
-
def object_class
|
69
|
-
self.class.to_s[/Services::([^:]+)/, 1].singularize.constantize
|
70
|
-
rescue
|
71
|
-
raise "Could not determine service class from #{self.class}"
|
72
|
-
end
|
73
|
-
|
74
70
|
def controller
|
75
71
|
@controller ||= begin
|
76
72
|
raise 'Please configure host.' if Services.configuration.host.nil?
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module Services
|
2
|
-
class
|
3
|
-
|
2
|
+
class Query
|
3
|
+
include ObjectClass
|
4
|
+
|
5
|
+
class << self
|
6
|
+
delegate :call, to: :new
|
7
|
+
end
|
4
8
|
|
5
9
|
def call(ids = [], conditions = {})
|
6
10
|
ids, conditions = Array(ids), conditions.symbolize_keys
|
@@ -14,7 +18,10 @@ module Services
|
|
14
18
|
|
15
19
|
unless conditions.empty?
|
16
20
|
scope = process(scope, conditions)
|
17
|
-
|
21
|
+
# If a JOIN is involved, use a subquery to make sure we're getting DISTINCT records.
|
22
|
+
if scope.to_sql =~ / join /i
|
23
|
+
scope = object_class.where(id: scope.select("DISTINCT #{object_table_id}"))
|
24
|
+
end
|
18
25
|
end
|
19
26
|
|
20
27
|
special_conditions.each do |k, v|
|
data/lib/services/railtie.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
module Services
|
2
2
|
class Railtie < Rails::Railtie
|
3
|
-
# Require
|
4
|
-
# on Rails.application to be present
|
5
|
-
initializer 'services.
|
6
|
-
require 'services/
|
3
|
+
# Require `Services::Query` here since it relies
|
4
|
+
# on Rails.application to be present.
|
5
|
+
initializer 'services.load_services_query' do
|
6
|
+
require 'services/query'
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
data/lib/services/version.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Services::
|
3
|
+
describe Services::Query do
|
4
4
|
include_context 'capture logs'
|
5
5
|
|
6
6
|
let(:base_find) { Services::Models::BaseFind }
|
7
7
|
|
8
8
|
it 'has call logging disabled by default' do
|
9
|
-
pending 'Rails has to be loaded to call
|
9
|
+
pending 'Rails has to be loaded to call Query'
|
10
10
|
expect(base_find.call_logging_disabled).to eq(true)
|
11
11
|
expect { base_find.call }.to_not change { logs }
|
12
12
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'services/
|
1
|
+
require 'services/query'
|
2
2
|
|
3
3
|
class Model
|
4
4
|
class << self
|
@@ -42,7 +42,7 @@ end
|
|
42
42
|
|
43
43
|
module Services
|
44
44
|
module Models
|
45
|
-
class
|
45
|
+
class Query < Services::Query
|
46
46
|
private
|
47
47
|
|
48
48
|
def process(scope, conditions)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: services
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Manuel Meurer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -153,21 +153,22 @@ files:
|
|
153
153
|
- lib/services.rb
|
154
154
|
- lib/services/asyncable.rb
|
155
155
|
- lib/services/base.rb
|
156
|
-
- lib/services/base_finder.rb
|
157
156
|
- lib/services/logger/file.rb
|
158
157
|
- lib/services/logger/redis.rb
|
159
158
|
- lib/services/modules/call_logger.rb
|
160
159
|
- lib/services/modules/exception_wrapper.rb
|
160
|
+
- lib/services/modules/object_class.rb
|
161
161
|
- lib/services/modules/uniqueness_checker.rb
|
162
|
+
- lib/services/query.rb
|
162
163
|
- lib/services/railtie.rb
|
163
164
|
- lib/services/version.rb
|
164
165
|
- services.gemspec
|
165
|
-
- spec/services/base_finder_spec.rb
|
166
166
|
- spec/services/base_spec.rb
|
167
167
|
- spec/services/logger/redis_spec.rb
|
168
168
|
- spec/services/modules/call_logger_spec.rb
|
169
169
|
- spec/services/modules/exception_wrapper_spec.rb
|
170
170
|
- spec/services/modules/uniqueness_checker_spec.rb
|
171
|
+
- spec/services/query_spec.rb
|
171
172
|
- spec/spec_helper.rb
|
172
173
|
- spec/support/call_proxy.rb
|
173
174
|
- spec/support/helpers.rb
|
@@ -201,12 +202,12 @@ signing_key:
|
|
201
202
|
specification_version: 4
|
202
203
|
summary: A nifty service layer for your Rails app
|
203
204
|
test_files:
|
204
|
-
- spec/services/base_finder_spec.rb
|
205
205
|
- spec/services/base_spec.rb
|
206
206
|
- spec/services/logger/redis_spec.rb
|
207
207
|
- spec/services/modules/call_logger_spec.rb
|
208
208
|
- spec/services/modules/exception_wrapper_spec.rb
|
209
209
|
- spec/services/modules/uniqueness_checker_spec.rb
|
210
|
+
- spec/services/query_spec.rb
|
210
211
|
- spec/spec_helper.rb
|
211
212
|
- spec/support/call_proxy.rb
|
212
213
|
- spec/support/helpers.rb
|