search_object 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +15 -1
- data/README.md +69 -16
- data/Rakefile +1 -1
- data/example/README.md +2 -2
- data/example/app/models/post_search.rb +2 -2
- data/lib/search_object/plugin/sorting.rb +3 -3
- data/lib/search_object/version.rb +1 -1
- data/search_object.gemspec +2 -2
- data/spec/search_object/base_spec.rb +3 -3
- data/spec/search_object/helper_spec.rb +5 -5
- data/spec/search_object/plugin/enum_spec.rb +6 -6
- data/spec/search_object/plugin/kaminari_spec.rb +1 -1
- data/spec/search_object/plugin/model_spec.rb +4 -0
- data/spec/search_object/plugin/sorting_spec.rb +21 -7
- data/spec/search_object/plugin/will_paginate_spec.rb +1 -1
- data/spec/support/paging_shared_example.rb +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: c19b1b27bb979fcee5671d55ef380f628fb8ba624c274166ad40aa8970d8ad2f
|
|
4
|
+
data.tar.gz: 4dc53dd30f010996cea99732d647d44d6d2d3eb07b8a39920b590dabdad5caa1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 702e7451fa287d3e98c75dc00fe0977ed4bc901fd72b4bd26fd18089c6abc200f0a03b78be6312b3217a3ecbb193b9a0346cf14834000aecd517968d41b5384b
|
|
7
|
+
data.tar.gz: 3b2cdb6312c1ac99afcbb1ea498339c6f732ab38bd45359af4ee84fc7543b5966bc6e5b797fb2525975c478fca4e10d5719487f8da9a87884de13cbcc9509bb5
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## Version 1.2.
|
|
3
|
+
## Version 1.2.1
|
|
4
|
+
|
|
5
|
+
* __[feature]__ Add `default:` option to `sort_by` plugin (@rstankov)
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
class ProductSearch
|
|
9
|
+
include SearchObject.module(:sorting)
|
|
10
|
+
|
|
11
|
+
scope { Product.all }
|
|
12
|
+
|
|
13
|
+
sort_by :name, :price, :created_at, default: 'price asc'
|
|
14
|
+
end
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Version 1.2.0
|
|
4
18
|
|
|
5
19
|
* __[feature]__ `enum` plugin added (@rstankov)
|
|
6
20
|
|
data/README.md
CHANGED
|
@@ -5,7 +5,40 @@
|
|
|
5
5
|
|
|
6
6
|
# SearchObject
|
|
7
7
|
|
|
8
|
-
In many of my projects I needed an object that performs several fairly complicated queries.
|
|
8
|
+
In many of my projects I needed an object that performs several fairly complicated queries. Most times I hand-coded them, but they would get complicated over time when other concerns like sorting, pagination and so are being added. So I decided to abstract this away and created ```SearchObject```, a DSL for creating such objects.
|
|
9
|
+
|
|
10
|
+
It is useful for:
|
|
11
|
+
|
|
12
|
+
- complicated search forms
|
|
13
|
+
- api endpoints with multiple filter conditions
|
|
14
|
+
- [GraphQL](https://rmosolgo.github.io/graphql-ruby/) resolvers
|
|
15
|
+
- ... search objects 😀
|
|
16
|
+
|
|
17
|
+
## Table of Contents
|
|
18
|
+
|
|
19
|
+
* [Installation](#installation)
|
|
20
|
+
* [Dependencies](#dependencies)
|
|
21
|
+
* [Usage](#usage)
|
|
22
|
+
* [Example](#example)
|
|
23
|
+
* [Plugins](#plugins)
|
|
24
|
+
* [Paginate Plugin](#paginate-plugin)
|
|
25
|
+
* [Enum Plugin](#enum-plugin)
|
|
26
|
+
* [Model Plugin](#model-plugin)
|
|
27
|
+
* [GraphQL Plugin](#graphql-plugin)
|
|
28
|
+
* [Sorting Plugin](#sorting-plugin)
|
|
29
|
+
* [Tips & Tricks](#tips--tricks)
|
|
30
|
+
* [Results Shortcut](#results-shortcut)
|
|
31
|
+
* [Passing Scope as Argument](#passing-scope-as-argument)
|
|
32
|
+
* [Handling Nil Options](#handling-nil-options)
|
|
33
|
+
* [Default Option Block](#default-option-block)
|
|
34
|
+
* [Using Instance Method in Option Blocks](#using-instance-method-in-option-blocks)
|
|
35
|
+
* [Using Instance Method for Straight Dispatch](#using-instance-method-for-straight-dispatch)
|
|
36
|
+
* [Active Record Is Not Required](#active-record-is-not-required)
|
|
37
|
+
* [Overwriting Methods](#overwriting-methods)
|
|
38
|
+
* [Extracting Basic Module](#extracting-basic-module#)
|
|
39
|
+
* [Contributing](#contributing)
|
|
40
|
+
* [License](#license)
|
|
41
|
+
|
|
9
42
|
|
|
10
43
|
## Installation
|
|
11
44
|
|
|
@@ -59,7 +92,7 @@ search.params # => option values
|
|
|
59
92
|
search.params opened: false # => overwrites the 'opened' option
|
|
60
93
|
```
|
|
61
94
|
|
|
62
|
-
|
|
95
|
+
### Example
|
|
63
96
|
|
|
64
97
|
You can find example of most important features and plugins - [here](https://github.com/RStankov/SearchObject/tree/master/example).
|
|
65
98
|
|
|
@@ -69,7 +102,7 @@ You can find example of most important features and plugins - [here](https://git
|
|
|
69
102
|
|
|
70
103
|
Plugins are just plain Ruby modules, which are included with ```SearchObject.module```. They are located under ```SearchObject::Plugin``` module.
|
|
71
104
|
|
|
72
|
-
### Paginate
|
|
105
|
+
### Paginate Plugin
|
|
73
106
|
|
|
74
107
|
Really simple paginate plugin, which uses the plain ```.limit``` and ```.offset``` methods.
|
|
75
108
|
|
|
@@ -104,7 +137,7 @@ include SearchObject.module(:will_paginate)
|
|
|
104
137
|
include SearchObject.module(:kaminari)
|
|
105
138
|
```
|
|
106
139
|
|
|
107
|
-
### Enum
|
|
140
|
+
### Enum Plugin
|
|
108
141
|
|
|
109
142
|
Gives you filter with pre-defined options.
|
|
110
143
|
|
|
@@ -135,7 +168,7 @@ class ProductSearch
|
|
|
135
168
|
end
|
|
136
169
|
```
|
|
137
170
|
|
|
138
|
-
### Model
|
|
171
|
+
### Model Plugin
|
|
139
172
|
|
|
140
173
|
Extends your search object with ```ActiveModel```, so you can use it in Rails forms.
|
|
141
174
|
|
|
@@ -161,7 +194,28 @@ end
|
|
|
161
194
|
<% end %>
|
|
162
195
|
```
|
|
163
196
|
|
|
164
|
-
###
|
|
197
|
+
### GraphQL Plugin
|
|
198
|
+
|
|
199
|
+
Installed as separate [gem](https://github.com/RStankov/SearchObjectGraphQL), it is designed to work with GraphQL:
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
gem 'search_object_graphql'
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
```ruby
|
|
206
|
+
class PostResolver
|
|
207
|
+
include SearchObject.module(:graphql)
|
|
208
|
+
|
|
209
|
+
type PostType
|
|
210
|
+
|
|
211
|
+
scope { Post.all }
|
|
212
|
+
|
|
213
|
+
option(:name, type: types.String) { |scope, value| scope.where name: value }
|
|
214
|
+
option(:published, type: types.Boolean) { |scope, value| value ? scope.published : scope.unpublished }
|
|
215
|
+
end
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Sorting Plugin
|
|
165
219
|
|
|
166
220
|
Fixing the pain of dealing with sorting attributes and directions.
|
|
167
221
|
|
|
@@ -197,7 +251,7 @@ search.sort_params_for('name')
|
|
|
197
251
|
|
|
198
252
|
## Tips & Tricks
|
|
199
253
|
|
|
200
|
-
### Results
|
|
254
|
+
### Results Shortcut
|
|
201
255
|
|
|
202
256
|
Very often you will just need results of search:
|
|
203
257
|
|
|
@@ -205,7 +259,7 @@ Very often you will just need results of search:
|
|
|
205
259
|
ProductSearch.new(params).results == ProductSearch.results(params)
|
|
206
260
|
```
|
|
207
261
|
|
|
208
|
-
### Passing
|
|
262
|
+
### Passing Scope as Argument
|
|
209
263
|
|
|
210
264
|
``` ruby
|
|
211
265
|
class ProductSearch
|
|
@@ -217,8 +271,7 @@ search = ProductSearch.new scope: Product.visible, filters: params[:f]
|
|
|
217
271
|
search.results # => includes only visible products
|
|
218
272
|
```
|
|
219
273
|
|
|
220
|
-
|
|
221
|
-
### Handling nil options
|
|
274
|
+
### Handling Nil Options
|
|
222
275
|
|
|
223
276
|
```ruby
|
|
224
277
|
class ProductSearch
|
|
@@ -231,7 +284,7 @@ class ProductSearch
|
|
|
231
284
|
end
|
|
232
285
|
```
|
|
233
286
|
|
|
234
|
-
### Default
|
|
287
|
+
### Default Option Block
|
|
235
288
|
|
|
236
289
|
```ruby
|
|
237
290
|
class ProductSearch
|
|
@@ -243,7 +296,7 @@ class ProductSearch
|
|
|
243
296
|
end
|
|
244
297
|
```
|
|
245
298
|
|
|
246
|
-
### Using
|
|
299
|
+
### Using Instance Method in Option Blocks
|
|
247
300
|
|
|
248
301
|
```ruby
|
|
249
302
|
class ProductSearch
|
|
@@ -261,7 +314,7 @@ class ProductSearch
|
|
|
261
314
|
end
|
|
262
315
|
```
|
|
263
316
|
|
|
264
|
-
### Using
|
|
317
|
+
### Using Instance Method for Straight Dispatch
|
|
265
318
|
|
|
266
319
|
```ruby
|
|
267
320
|
class ProductSearch
|
|
@@ -279,7 +332,7 @@ class ProductSearch
|
|
|
279
332
|
end
|
|
280
333
|
```
|
|
281
334
|
|
|
282
|
-
### Active Record
|
|
335
|
+
### Active Record Is Not Required
|
|
283
336
|
|
|
284
337
|
```ruby
|
|
285
338
|
class ProductSearch
|
|
@@ -292,7 +345,7 @@ class ProductSearch
|
|
|
292
345
|
end
|
|
293
346
|
```
|
|
294
347
|
|
|
295
|
-
### Overwriting
|
|
348
|
+
### Overwriting Methods
|
|
296
349
|
|
|
297
350
|
You can have fine grained scope, by overwriting ```initialize``` method:
|
|
298
351
|
|
|
@@ -333,7 +386,7 @@ class ProductSearch
|
|
|
333
386
|
end
|
|
334
387
|
```
|
|
335
388
|
|
|
336
|
-
### Extracting
|
|
389
|
+
### Extracting Basic Module
|
|
337
390
|
|
|
338
391
|
You can extarct a basic search class for your application.
|
|
339
392
|
|
data/Rakefile
CHANGED
data/example/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# SearchObject
|
|
1
|
+
# SearchObject Example Rails Application
|
|
2
2
|
|
|
3
3
|
This is example application showing, one of the possible usages of ```SearchObject```. It showcases the following features:
|
|
4
4
|
|
|
5
5
|
* Basic search object functionality
|
|
6
6
|
* Default options
|
|
7
7
|
* Using private method helpers in options
|
|
8
|
-
* Plugins: model, sorting, will_paginate
|
|
8
|
+
* Plugins: model, sorting, will_paginate, enum
|
|
9
9
|
|
|
10
10
|
## Interesting files:
|
|
11
11
|
|
|
@@ -15,7 +15,7 @@ class PostSearch
|
|
|
15
15
|
|
|
16
16
|
option :term, with: :apply_term
|
|
17
17
|
|
|
18
|
-
option :rating, enum: %i
|
|
18
|
+
option :rating, enum: %i[low high]
|
|
19
19
|
|
|
20
20
|
option :title do |scope, value|
|
|
21
21
|
scope.where 'title LIKE ?', escape_search_term(value)
|
|
@@ -51,7 +51,7 @@ class PostSearch
|
|
|
51
51
|
|
|
52
52
|
def parse_date(value)
|
|
53
53
|
Date.parse(value).strftime('%Y-%m-%d')
|
|
54
|
-
rescue
|
|
54
|
+
rescue ArgumentError
|
|
55
55
|
nil
|
|
56
56
|
end
|
|
57
57
|
|
|
@@ -19,7 +19,7 @@ module SearchObject
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def sort_direction
|
|
22
|
-
@sort_direction ||= Helper.ensure_included sort.to_s.split(' ', 2).last, %w
|
|
22
|
+
@sort_direction ||= Helper.ensure_included sort.to_s.split(' ', 2).last, %w[desc asc]
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def sort_direction_for(attribute)
|
|
@@ -40,9 +40,9 @@ module SearchObject
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
module ClassMethods
|
|
43
|
-
def sort_by(*attributes)
|
|
43
|
+
def sort_by(*attributes, default: nil)
|
|
44
44
|
config[:sort_attributes] = attributes.map(&:to_s)
|
|
45
|
-
config[:defaults]['sort'] = "#{config[:sort_attributes].first} desc"
|
|
45
|
+
config[:defaults]['sort'] = default || "#{config[:sort_attributes].first} desc"
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def sort_attributes
|
data/search_object.gemspec
CHANGED
|
@@ -29,6 +29,6 @@ Gem::Specification.new do |spec|
|
|
|
29
29
|
spec.add_development_dependency 'will_paginate'
|
|
30
30
|
spec.add_development_dependency 'kaminari'
|
|
31
31
|
spec.add_development_dependency 'kaminari-activerecord'
|
|
32
|
-
spec.add_development_dependency 'rubocop', '0.
|
|
33
|
-
spec.add_development_dependency 'rubocop-rspec', '1.
|
|
32
|
+
spec.add_development_dependency 'rubocop', '0.51.0'
|
|
33
|
+
spec.add_development_dependency 'rubocop-rspec', '1.20.1'
|
|
34
34
|
end
|
|
@@ -77,7 +77,7 @@ module SearchObject
|
|
|
77
77
|
expect(inequality_search.new(filters: { value: 1 }).results).to eq [2, 3]
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
describe 'scope' do
|
|
81
81
|
def search_class
|
|
82
82
|
define_search_class do
|
|
83
83
|
option :name do
|
|
@@ -258,11 +258,11 @@ module SearchObject
|
|
|
258
258
|
|
|
259
259
|
describe '#results?' do
|
|
260
260
|
it 'returns true if there are results' do
|
|
261
|
-
expect(new_search([1, 2, 3], value: 1)
|
|
261
|
+
expect(new_search([1, 2, 3], value: 1)).to be_results
|
|
262
262
|
end
|
|
263
263
|
|
|
264
264
|
it 'returns false if there are no results' do
|
|
265
|
-
expect(new_search([1, 2, 3], value: 4)
|
|
265
|
+
expect(new_search([1, 2, 3], value: 4)).not_to be_results
|
|
266
266
|
end
|
|
267
267
|
end
|
|
268
268
|
|
|
@@ -18,12 +18,12 @@ module SearchObject
|
|
|
18
18
|
|
|
19
19
|
describe '.slice_keys' do
|
|
20
20
|
it 'selects only given keys' do
|
|
21
|
-
hash = described_class.slice_keys({ a: 1, b: 2, c: 3 }, [
|
|
21
|
+
hash = described_class.slice_keys({ a: 1, b: 2, c: 3 }, %i[a b])
|
|
22
22
|
expect(hash).to eq a: 1, b: 2
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
it 'ignores not existing keys' do
|
|
26
|
-
hash = described_class.slice_keys({}, [
|
|
26
|
+
hash = described_class.slice_keys({}, %i[a b])
|
|
27
27
|
expect(hash).to eq({})
|
|
28
28
|
end
|
|
29
29
|
end
|
|
@@ -43,15 +43,15 @@ module SearchObject
|
|
|
43
43
|
|
|
44
44
|
describe '.normalize_filters' do
|
|
45
45
|
it 'combines defaults and filters' do
|
|
46
|
-
expect(described_class.normalize_params({ 'a' => 1, 'b' => 2 }, { a: 2 }, %w
|
|
46
|
+
expect(described_class.normalize_params({ 'a' => 1, 'b' => 2 }, { a: 2 }, %w[a b])).to eq 'a' => 2, 'b' => 2
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
it 'excludes non specified keys' do
|
|
50
|
-
expect(described_class.normalize_params({ 'a' => 1 }, { b: 2 }, %w
|
|
50
|
+
expect(described_class.normalize_params({ 'a' => 1 }, { b: 2 }, %w[a])).to eq 'a' => 1
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
it 'handles missing defaults' do
|
|
54
|
-
expect(described_class.normalize_params(nil, { a: 1 }, %w
|
|
54
|
+
expect(described_class.normalize_params(nil, { a: 1 }, %w[a])).to eq 'a' => 1
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
it 'handles missing filters' do
|
|
@@ -9,7 +9,7 @@ module SearchObject
|
|
|
9
9
|
|
|
10
10
|
scope { [1, 2, 3, 4, 5] }
|
|
11
11
|
|
|
12
|
-
option :filter, enum: %w
|
|
12
|
+
option :filter, enum: %w[odd even]
|
|
13
13
|
|
|
14
14
|
private
|
|
15
15
|
|
|
@@ -45,7 +45,7 @@ module SearchObject
|
|
|
45
45
|
Class.new do
|
|
46
46
|
include SearchObject.module(:enum)
|
|
47
47
|
|
|
48
|
-
option(:filter, enum: %w
|
|
48
|
+
option(:filter, enum: %w[a b]) { |_scope, _value| nil }
|
|
49
49
|
end
|
|
50
50
|
end.to raise_error Enum::BlockIgnoredError
|
|
51
51
|
end
|
|
@@ -55,7 +55,7 @@ module SearchObject
|
|
|
55
55
|
Class.new do
|
|
56
56
|
include SearchObject.module(:enum)
|
|
57
57
|
|
|
58
|
-
option :filter, enum: %w
|
|
58
|
+
option :filter, enum: %w[a b], with: :method_name
|
|
59
59
|
end
|
|
60
60
|
end.to raise_error Enum::WithIgnoredError
|
|
61
61
|
end
|
|
@@ -91,10 +91,10 @@ module SearchObject
|
|
|
91
91
|
end
|
|
92
92
|
end
|
|
93
93
|
|
|
94
|
-
scope = %w
|
|
94
|
+
scope = %w[name age location]
|
|
95
95
|
|
|
96
|
-
expect(call(object: object, option: 'select', scope: scope, value: 'name')).to eq %w
|
|
97
|
-
expect(call(object: object, option: 'select', scope: scope, value: 'age')).to eq %w
|
|
96
|
+
expect(call(object: object, option: 'select', scope: scope, value: 'name')).to eq %w[name]
|
|
97
|
+
expect(call(object: object, option: 'select', scope: scope, value: 'age')).to eq %w[age]
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
it 'raises NoMethodError when object can not handle enum method' do
|
|
@@ -39,6 +39,10 @@ module SearchObject
|
|
|
39
39
|
expect(value).to eq(expected_value), message
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
def assert_respond_to(object, method, message = nil)
|
|
43
|
+
expect(object).to respond_to(method), message
|
|
44
|
+
end
|
|
45
|
+
|
|
42
46
|
ActiveModel::Lint::Tests.public_instance_methods.map(&:to_s).grep(/^test/).each do |method|
|
|
43
47
|
example(method.tr('_', ' ')) { send method }
|
|
44
48
|
end
|
|
@@ -39,10 +39,24 @@ module SearchObject
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
it 'defaults to first sort by option' do
|
|
42
|
+
search_class = Class.new do
|
|
43
|
+
include SearchObject.module(:sorting)
|
|
44
|
+
|
|
45
|
+
scope { Product.all }
|
|
46
|
+
|
|
47
|
+
sort_by :name, :price, :created_at, default: :price
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
5.times { |i| Product.create! price: i }
|
|
51
|
+
|
|
52
|
+
expect(search_class.new.results.map(&:price)).to eq [4, 3, 2, 1, 0]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'accepts default sorting' do
|
|
42
56
|
5.times { |i| Product.create! name: "Name#{i}" }
|
|
43
57
|
|
|
44
58
|
search = search_with_sort
|
|
45
|
-
expect(search.results.map(&:name)).to eq %w
|
|
59
|
+
expect(search.results.map(&:name)).to eq %w[Name4 Name3 Name2 Name1 Name0]
|
|
46
60
|
end
|
|
47
61
|
|
|
48
62
|
it 'ignores invalid sort values' do
|
|
@@ -67,22 +81,22 @@ module SearchObject
|
|
|
67
81
|
it 'matches the sort option' do
|
|
68
82
|
search = search_with_sort 'price desc'
|
|
69
83
|
|
|
70
|
-
expect(search
|
|
71
|
-
expect(search.
|
|
84
|
+
expect(search).to be_sort :price
|
|
85
|
+
expect(search).not_to be_sort :name
|
|
72
86
|
end
|
|
73
87
|
|
|
74
88
|
it 'matches string also' do
|
|
75
89
|
search = search_with_sort 'price desc'
|
|
76
90
|
|
|
77
|
-
expect(search.
|
|
78
|
-
expect(search.
|
|
91
|
+
expect(search).to be_sort 'price'
|
|
92
|
+
expect(search).not_to be_sort 'name'
|
|
79
93
|
end
|
|
80
94
|
|
|
81
95
|
it 'matches exact strings' do
|
|
82
96
|
search = search_with_sort 'price desc'
|
|
83
97
|
|
|
84
|
-
expect(search.
|
|
85
|
-
expect(search.
|
|
98
|
+
expect(search).to be_sort 'price desc'
|
|
99
|
+
expect(search).not_to be_sort 'price asc'
|
|
86
100
|
end
|
|
87
101
|
end
|
|
88
102
|
|
|
@@ -9,7 +9,7 @@ module SearchObject
|
|
|
9
9
|
it_behaves_like 'a paging plugin' do
|
|
10
10
|
it 'uses will_paginate gem' do
|
|
11
11
|
search = search_with_page
|
|
12
|
-
expect(search.results
|
|
12
|
+
expect(search.results).to be_respond_to :total_entries
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
end
|
|
@@ -37,7 +37,7 @@ shared_examples_for 'a paging plugin' do
|
|
|
37
37
|
6.times { |i| Product.create name: "product_#{i}" }
|
|
38
38
|
search = search_with_page 2, 2
|
|
39
39
|
|
|
40
|
-
expect(search.results.map(&:name)).to eq %w
|
|
40
|
+
expect(search.results.map(&:name)).to eq %w[product_2 product_3]
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: search_object
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.2.
|
|
4
|
+
version: 1.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Radoslav Stankov
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2018-05-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -170,28 +170,28 @@ dependencies:
|
|
|
170
170
|
requirements:
|
|
171
171
|
- - '='
|
|
172
172
|
- !ruby/object:Gem::Version
|
|
173
|
-
version: 0.
|
|
173
|
+
version: 0.51.0
|
|
174
174
|
type: :development
|
|
175
175
|
prerelease: false
|
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
|
177
177
|
requirements:
|
|
178
178
|
- - '='
|
|
179
179
|
- !ruby/object:Gem::Version
|
|
180
|
-
version: 0.
|
|
180
|
+
version: 0.51.0
|
|
181
181
|
- !ruby/object:Gem::Dependency
|
|
182
182
|
name: rubocop-rspec
|
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
|
184
184
|
requirements:
|
|
185
185
|
- - '='
|
|
186
186
|
- !ruby/object:Gem::Version
|
|
187
|
-
version: 1.
|
|
187
|
+
version: 1.20.1
|
|
188
188
|
type: :development
|
|
189
189
|
prerelease: false
|
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
|
191
191
|
requirements:
|
|
192
192
|
- - '='
|
|
193
193
|
- !ruby/object:Gem::Version
|
|
194
|
-
version: 1.
|
|
194
|
+
version: 1.20.1
|
|
195
195
|
description: Search object DSL
|
|
196
196
|
email:
|
|
197
197
|
- rstankov@gmail.com
|
|
@@ -294,7 +294,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
294
294
|
version: '0'
|
|
295
295
|
requirements: []
|
|
296
296
|
rubyforge_project:
|
|
297
|
-
rubygems_version: 2.
|
|
297
|
+
rubygems_version: 2.7.6
|
|
298
298
|
signing_key:
|
|
299
299
|
specification_version: 4
|
|
300
300
|
summary: Provides DSL for creating search objects
|