queryko 1.2.1.beta2 → 1.2.2
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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +71 -13
- data/lib/queryko/able.rb +5 -5
- data/lib/queryko/base.rb +127 -0
- data/lib/queryko/feature.rb +12 -15
- data/lib/queryko/filter_classes.rb +41 -0
- data/lib/queryko/query_object.rb +9 -125
- data/lib/queryko/range_attributes.rb +1 -0
- data/lib/queryko/searchables.rb +1 -1
- data/lib/queryko/version.rb +1 -1
- data/lib/queryko.rb +2 -6
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a59be1cc920578cfddb7246f18fe1435ed9ef7517610bf3ec2f41fe0c5a5556
|
4
|
+
data.tar.gz: 14adefec70cd53df2224961010a3118dd5703aa6d094c150ae54622718d81f6d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad6636ad9562467fd758633f97972a885c377b405038f03ed95e9d263e3285ae68dfd07687c22357d2b477187537837a476c9dc0ca303b16e50cef6f53ffff7c
|
7
|
+
data.tar.gz: fa822897bea178f2a853b18e86afb0266c5427b97894895aa926ac1e61fe97b8bac025bf34a08902403e7e9a5c2850c375a59833f2ebb9a7bfdba07534c98474
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
This gem provides additional functionality on your query objects. It will filter and paginate your query by supplying arguments directly from controller params
|
4
4
|
|
5
5
|
## Installation
|
6
|
+
|
6
7
|
```ruby
|
7
8
|
# Pagination
|
8
9
|
gem 'kaminari'
|
@@ -22,33 +23,38 @@ Or install it yourself as:
|
|
22
23
|
$ gem install queryko
|
23
24
|
|
24
25
|
## Usage
|
26
|
+
|
25
27
|
### Create a query object
|
28
|
+
|
26
29
|
``` ruby
|
27
30
|
class ProductsQuery < Queryko::QueryObject
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
super(params, relation)
|
35
|
-
end
|
31
|
+
feature :created_at, :min
|
32
|
+
feature :created_at, :max
|
33
|
+
feature :price, :min
|
34
|
+
feature :price, :max
|
35
|
+
feature :name, :search, as: :name
|
36
|
+
feature :vendor, :search, as: :vendor
|
36
37
|
end
|
37
38
|
```
|
38
39
|
|
39
40
|
### Using your query object
|
40
|
-
Filter your query by appending `_min` or `_max` on your defined attributes. You can also filter
|
41
|
-
|
41
|
+
Filter your query by appending `_min` or `_max` on your defined attributes. You can also filter results by attribute with your defined feature.
|
42
|
+
|
42
43
|
``` ruby
|
43
44
|
# Collection
|
44
45
|
products = ProductsQuery.new(price_min: 100, price_max: 150, name: 'Milk').call
|
45
46
|
products = ProductsQuery.new(since_id: 26).call
|
46
47
|
|
47
|
-
# Count
|
48
|
+
# Count - Counts items on current page. Default page is 1
|
48
49
|
products = ProductsQuery.new(created_at_min: 'Jan 1, 2019').count
|
49
50
|
products = ProductsQuery.new(name: 'Bag').count
|
51
|
+
|
52
|
+
# Total Count - Counts all items matching defined conditions
|
53
|
+
products = ProductsQuery.new(created_at_min: 'Jan 1, 2019').total_count
|
54
|
+
products = ProductsQuery.new(name: 'Bag').total_count
|
50
55
|
```
|
51
56
|
|
57
|
+
|
52
58
|
#### Object Methods
|
53
59
|
- **count** - Returns the filtered count including pagination filter or the size of return object.
|
54
60
|
- **total_count** - Returns the overall count of the filtered total records.
|
@@ -62,19 +68,71 @@ query = ProductsQuery.new(page: 5, limit: 5)
|
|
62
68
|
query.count # 1
|
63
69
|
query.total_count # 21
|
64
70
|
```
|
71
|
+
### Pagination
|
72
|
+
Override these methods to customize pagination limits
|
73
|
+
|
74
|
+
``` ruby
|
75
|
+
...
|
76
|
+
|
77
|
+
def upper_limit
|
78
|
+
20 # default is 100
|
79
|
+
end
|
80
|
+
|
81
|
+
def lower_limit
|
82
|
+
5 # default is 10
|
83
|
+
end
|
84
|
+
|
85
|
+
def default_limit
|
86
|
+
10 # default is 50
|
87
|
+
end
|
88
|
+
|
89
|
+
...
|
90
|
+
```
|
91
|
+
|
92
|
+
### Custom Filters
|
93
|
+
Create a custom filter class using `Queryko::Filters::Base`
|
94
|
+
|
95
|
+
``` ruby
|
96
|
+
class CustomFilters::CoolSearch < Queryko::Filters::Base
|
97
|
+
|
98
|
+
# Optional.
|
99
|
+
# Some `options` keys are reserved for basic functionality
|
100
|
+
# Use `options` to get data from feature definition
|
101
|
+
def intialize(options = {}, feature)
|
102
|
+
super options, feature
|
103
|
+
end
|
104
|
+
|
105
|
+
# Required. This method is called by query object. Always return the result of
|
106
|
+
# the collection
|
107
|
+
def perform(collection, token)
|
108
|
+
collection.where("#{table_name}.#{column_name} < ?", "Cool-#{token}")
|
109
|
+
end
|
110
|
+
end
|
111
|
+
```
|
112
|
+
|
113
|
+
Then add the filter class to your Queryko::Base object
|
114
|
+
``` ruby
|
115
|
+
class QueryObject < Queryko::Base
|
116
|
+
filter_class :cool_search, CustomFilters::CoolSearch
|
117
|
+
# or
|
118
|
+
filter_class :cool_search, "CustomFilters::CoolSearch"
|
119
|
+
|
120
|
+
|
121
|
+
feature :name, :cool_search
|
122
|
+
# the :name will be scoped using params[:name_cool_search]
|
123
|
+
end
|
124
|
+
```
|
65
125
|
|
66
126
|
### Other available options
|
67
127
|
| Option | description |
|
68
128
|
|:---------|:-----------------------------|
|
69
129
|
| since_id | retrieves records after `id` |
|
70
130
|
| page | page to retrieve |
|
71
|
-
| limit | number of records per page |
|
72
131
|
|
73
132
|
## Contributing
|
74
133
|
|
75
134
|
Bug reports and pull requests are welcome on GitHub at https://github.com/neume/queryko. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
76
135
|
|
77
|
-
|
78
136
|
## License
|
79
137
|
|
80
138
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/lib/queryko/able.rb
CHANGED
@@ -3,10 +3,10 @@ module Queryko
|
|
3
3
|
def self.included(base)
|
4
4
|
base.extend(ClassMethods)
|
5
5
|
base.class_eval do
|
6
|
-
class_attribute :
|
6
|
+
class_attribute :defined_filters, default: {}, instance_writer: false
|
7
7
|
class_attribute :features, default: {}, instance_writer: false
|
8
8
|
class_attribute :fields, default: {}, instance_writer: false
|
9
|
-
self.
|
9
|
+
self.defined_filters = {}
|
10
10
|
self.features = {}
|
11
11
|
self.fields = {}
|
12
12
|
|
@@ -18,11 +18,11 @@ module Queryko
|
|
18
18
|
def feature(feature_name, filter, options = {})
|
19
19
|
# returns the feature if it exists
|
20
20
|
feat = self.features[feature_name.to_sym] ||= Queryko::Feature.new feature_name, self
|
21
|
-
self.
|
21
|
+
self.defined_filters[filter] ||= Array.new
|
22
22
|
|
23
23
|
# creates a filter
|
24
|
-
filt = feat.
|
25
|
-
self.
|
24
|
+
filt = feat.add_filter filter, options
|
25
|
+
self.defined_filters[filter].push(filt)
|
26
26
|
|
27
27
|
# appends new field
|
28
28
|
self.fields[filt.field.to_sym] ||= Array.new
|
data/lib/queryko/base.rb
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
require "active_support/core_ext/class/attribute"
|
2
|
+
require "queryko/range_attributes"
|
3
|
+
require "queryko/searchables"
|
4
|
+
require "queryko/after_attributes"
|
5
|
+
require "queryko/naming"
|
6
|
+
require "queryko/able"
|
7
|
+
require "queryko/filterer"
|
8
|
+
require "queryko/filter_classes"
|
9
|
+
|
10
|
+
module Queryko
|
11
|
+
class Base
|
12
|
+
attr_reader :countable_resource
|
13
|
+
include Queryko::FilterClasses
|
14
|
+
include Queryko::Naming
|
15
|
+
include Queryko::RangeAttributes
|
16
|
+
include Queryko::Searchables
|
17
|
+
include Queryko::Able
|
18
|
+
include Queryko::Filterer
|
19
|
+
# include AfterAttributes
|
20
|
+
|
21
|
+
def self.inherited(subclass)
|
22
|
+
# It should not be executed when using anonymous class
|
23
|
+
subclass.table_name inferred_from_class_name(subclass) if subclass.name
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(params = {}, rel)
|
27
|
+
@relation = @original_relation = rel || inferred_model.all
|
28
|
+
@params = params
|
29
|
+
end
|
30
|
+
|
31
|
+
def call
|
32
|
+
perform
|
33
|
+
self.relation = paginate if config[:paginate]
|
34
|
+
return relation
|
35
|
+
end
|
36
|
+
|
37
|
+
def perform
|
38
|
+
return if @performed
|
39
|
+
|
40
|
+
@performed = true
|
41
|
+
pre_filter
|
42
|
+
filter
|
43
|
+
filter_by_filters
|
44
|
+
@countable_resource = relation
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def total_count
|
49
|
+
perform
|
50
|
+
countable_resource.count
|
51
|
+
end
|
52
|
+
|
53
|
+
def count
|
54
|
+
call.to_a.count
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
attr_reader :params, :relation
|
60
|
+
attr_writer :relation
|
61
|
+
|
62
|
+
def config
|
63
|
+
@config ||= {
|
64
|
+
paginate: true,
|
65
|
+
since_id: true,
|
66
|
+
ids: true
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def pre_filter
|
71
|
+
self.relation = by_ids if config[:ids] && params[:ids]
|
72
|
+
self.relation = since_id if config[:since_id] && params[:since_id]
|
73
|
+
end
|
74
|
+
|
75
|
+
def filter
|
76
|
+
end
|
77
|
+
|
78
|
+
def paginate
|
79
|
+
if defined?(WillPaginate)
|
80
|
+
relation.paginate(page: page, per_page: limit)
|
81
|
+
elsif defined?(Kaminari)
|
82
|
+
relation.page(page).per(limit)
|
83
|
+
else
|
84
|
+
raise 'Only kaminari and wil_paginate are supported'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def page
|
89
|
+
params[:page] || 1
|
90
|
+
end
|
91
|
+
|
92
|
+
def limit
|
93
|
+
@limit ||= get_limit
|
94
|
+
end
|
95
|
+
|
96
|
+
def get_limit
|
97
|
+
lim = (params[:limit] || default_limit).to_i
|
98
|
+
if lower_limit > lim
|
99
|
+
lower_limit
|
100
|
+
elsif lim > upper_limit
|
101
|
+
upper_limit
|
102
|
+
else
|
103
|
+
lim
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def upper_limit
|
108
|
+
100
|
109
|
+
end
|
110
|
+
|
111
|
+
def default_limit
|
112
|
+
50
|
113
|
+
end
|
114
|
+
|
115
|
+
def lower_limit
|
116
|
+
10
|
117
|
+
end
|
118
|
+
|
119
|
+
def by_ids
|
120
|
+
relation.where(id: params[:ids].split(','))
|
121
|
+
end
|
122
|
+
|
123
|
+
def since_id
|
124
|
+
relation.where("#{defined_table_name}.id > ?", params[:since_id])
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
data/lib/queryko/feature.rb
CHANGED
@@ -1,28 +1,25 @@
|
|
1
1
|
class Queryko::Feature
|
2
|
-
attr_reader :name, :
|
2
|
+
attr_reader :name, :filter_names, :query_object
|
3
3
|
def initialize(name, query_object)
|
4
4
|
@name = name
|
5
5
|
@query_object = query_object
|
6
|
-
@
|
6
|
+
@filter_names = {}
|
7
7
|
end
|
8
8
|
|
9
9
|
def add_filter(filter_name, options = {})
|
10
|
-
self.
|
10
|
+
self.filter_names[filter_name] = create_filter(filter_name, options)
|
11
11
|
end
|
12
12
|
|
13
13
|
def create_filter(filter_name, options = {})
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
result = filters[:before] ||= Queryko::Filters::Before.new(options, self)
|
19
|
-
when :min
|
20
|
-
result = filters[:min] ||= Queryko::Filters::Min.new(options, self)
|
21
|
-
when :max
|
22
|
-
result = filters[:max] ||= Queryko::Filters::Max.new(options, self)
|
23
|
-
when :search
|
24
|
-
result = filters[:search] ||= Queryko::Filters::Search.new(options, self)
|
14
|
+
if filter_class = filter_class_for(filter_name)
|
15
|
+
result = filter_class.new(options, self)
|
16
|
+
else
|
17
|
+
raise "Filter class for #{filter_name} not found"
|
25
18
|
end
|
26
19
|
result
|
27
|
-
|
20
|
+
end
|
21
|
+
|
22
|
+
def filter_class_for(filter_name)
|
23
|
+
self.query_object.filters.fetch(filter_name.to_sym)
|
24
|
+
end
|
28
25
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "queryko/filters/base"
|
2
|
+
require "queryko/filters/after"
|
3
|
+
require "queryko/filters/before"
|
4
|
+
require "queryko/filters/min"
|
5
|
+
require "queryko/filters/max"
|
6
|
+
require "queryko/filters/search"
|
7
|
+
|
8
|
+
module Queryko
|
9
|
+
module FilterClasses
|
10
|
+
def self.included(base)
|
11
|
+
base.extend(ClassMethods)
|
12
|
+
base.class_eval do
|
13
|
+
class_attribute :filters, default: {}
|
14
|
+
load_defaults
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
def load_defaults
|
20
|
+
self.filters = {
|
21
|
+
after: Queryko::Filters::After,
|
22
|
+
before: Queryko::Filters::Before,
|
23
|
+
min: Queryko::Filters::Min,
|
24
|
+
max: Queryko::Filters::Max,
|
25
|
+
search: Queryko::Filters::Search
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def filter_class(symbol, klass)
|
30
|
+
filters[symbol.to_sym] = constantize_class(klass)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def constantize_class(klass)
|
36
|
+
return klass unless klass.class == String
|
37
|
+
klass.constantize
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/queryko/query_object.rb
CHANGED
@@ -1,125 +1,9 @@
|
|
1
|
-
require "
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
class QueryObject
|
11
|
-
attr_reader :countable_resource
|
12
|
-
include Queryko::Naming
|
13
|
-
include Queryko::RangeAttributes
|
14
|
-
include Queryko::Searchables
|
15
|
-
include Queryko::Able
|
16
|
-
include Queryko::Filterer
|
17
|
-
# include AfterAttributes
|
18
|
-
|
19
|
-
def self.inherited(subclass)
|
20
|
-
# It should not be executed when using anonymous class
|
21
|
-
subclass.table_name inferred_from_class_name(subclass) if subclass.name
|
22
|
-
end
|
23
|
-
|
24
|
-
def initialize(params = {}, rel)
|
25
|
-
@relation = @original_relation = rel || inferred_model.all
|
26
|
-
@params = params
|
27
|
-
end
|
28
|
-
|
29
|
-
def call
|
30
|
-
perform
|
31
|
-
self.relation = paginate if config[:paginate]
|
32
|
-
return relation
|
33
|
-
end
|
34
|
-
|
35
|
-
def perform
|
36
|
-
return if @performed
|
37
|
-
|
38
|
-
@performed = true
|
39
|
-
pre_filter
|
40
|
-
filter
|
41
|
-
filter_by_filters
|
42
|
-
@countable_resource = relation
|
43
|
-
end
|
44
|
-
|
45
|
-
|
46
|
-
def total_count
|
47
|
-
perform
|
48
|
-
countable_resource.count
|
49
|
-
end
|
50
|
-
|
51
|
-
def count
|
52
|
-
call.to_a.count
|
53
|
-
end
|
54
|
-
|
55
|
-
private
|
56
|
-
|
57
|
-
attr_reader :params, :relation
|
58
|
-
attr_writer :relation
|
59
|
-
|
60
|
-
def config
|
61
|
-
@config ||= {
|
62
|
-
paginate: true,
|
63
|
-
since_id: true,
|
64
|
-
ids: true
|
65
|
-
}
|
66
|
-
end
|
67
|
-
|
68
|
-
def pre_filter
|
69
|
-
self.relation = by_ids if config[:ids] && params[:ids]
|
70
|
-
self.relation = since_id if config[:since_id] && params[:since_id]
|
71
|
-
end
|
72
|
-
|
73
|
-
def filter
|
74
|
-
end
|
75
|
-
|
76
|
-
def paginate
|
77
|
-
if defined?(WillPaginate)
|
78
|
-
relation.paginate(page: page, per_page: limit)
|
79
|
-
elsif defined?(Kaminari)
|
80
|
-
relation.page(page).per(limit)
|
81
|
-
else
|
82
|
-
raise 'Only kaminari and wil_paginate are supported'
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def page
|
87
|
-
params[:page] || 1
|
88
|
-
end
|
89
|
-
|
90
|
-
def limit
|
91
|
-
@limit ||= get_limit
|
92
|
-
end
|
93
|
-
|
94
|
-
def get_limit
|
95
|
-
lim = (params[:limit] || default_limit).to_i
|
96
|
-
if lower_limit > lim
|
97
|
-
lower_limit
|
98
|
-
elsif lim > upper_limit
|
99
|
-
upper_limit
|
100
|
-
else
|
101
|
-
lim
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def upper_limit
|
106
|
-
100
|
107
|
-
end
|
108
|
-
|
109
|
-
def default_limit
|
110
|
-
50
|
111
|
-
end
|
112
|
-
|
113
|
-
def lower_limit
|
114
|
-
10
|
115
|
-
end
|
116
|
-
|
117
|
-
def by_ids
|
118
|
-
relation.where(id: params[:ids].split(','))
|
119
|
-
end
|
120
|
-
|
121
|
-
def since_id
|
122
|
-
relation.where("#{defined_table_name}.id > ?", params[:since_id])
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
1
|
+
require "queryko/base"
|
2
|
+
Queryko::QueryObject = Queryko::Base
|
3
|
+
|
4
|
+
message = [
|
5
|
+
"[DEPRECATION] Inheriting from 'Queryko::QueryObject' is depcrecated",
|
6
|
+
"and will be removed on next major release.",
|
7
|
+
"Inherit form 'Queryko::Base' instead."
|
8
|
+
]
|
9
|
+
warn message.join(' ')
|
@@ -11,6 +11,7 @@ module Queryko
|
|
11
11
|
feature arg.to_sym, :min
|
12
12
|
feature arg.to_sym, :max
|
13
13
|
suggestion << "feature :#{arg}, :min"
|
14
|
+
suggestion << "feature :#{arg}, :max"
|
14
15
|
end
|
15
16
|
warn "[DEPRECATION] `add_range_attributes` is deprecated. Please use `feature` instead.\nExample:\n#{suggestion.join("\n")}"
|
16
17
|
end
|
data/lib/queryko/searchables.rb
CHANGED
@@ -9,7 +9,7 @@ module Queryko
|
|
9
9
|
suggestion = []
|
10
10
|
args.each do |arg|
|
11
11
|
feature arg.to_sym, :search, as: arg.to_sym
|
12
|
-
suggestion << "feature :#{arg}, :search, as:
|
12
|
+
suggestion << "feature :#{arg}, :search, as: :#{arg}"
|
13
13
|
end
|
14
14
|
warn "[DEPRECATION] `add_searchables` is deprecated. Please use `feature` instead.\nExample:\n#{suggestion.join("\n")}"
|
15
15
|
end
|
data/lib/queryko/version.rb
CHANGED
data/lib/queryko.rb
CHANGED
@@ -1,14 +1,10 @@
|
|
1
1
|
require "queryko/version"
|
2
2
|
require "queryko/query_object"
|
3
|
-
require "queryko/
|
4
|
-
require "queryko/filters/after"
|
5
|
-
require "queryko/filters/before"
|
6
|
-
require "queryko/filters/min"
|
7
|
-
require "queryko/filters/max"
|
8
|
-
require "queryko/filters/search"
|
3
|
+
require "queryko/base"
|
9
4
|
require "queryko/feature"
|
10
5
|
require "queryko/able"
|
11
6
|
require "queryko/filterer"
|
7
|
+
require "queryko/filter_classes"
|
12
8
|
module Queryko
|
13
9
|
# Your code goes here...
|
14
10
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: queryko
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joseph Nelson Valeros
|
@@ -145,7 +145,9 @@ files:
|
|
145
145
|
- lib/queryko.rb
|
146
146
|
- lib/queryko/able.rb
|
147
147
|
- lib/queryko/after_attributes.rb
|
148
|
+
- lib/queryko/base.rb
|
148
149
|
- lib/queryko/feature.rb
|
150
|
+
- lib/queryko/filter_classes.rb
|
149
151
|
- lib/queryko/filterer.rb
|
150
152
|
- lib/queryko/filters/after.rb
|
151
153
|
- lib/queryko/filters/base.rb
|
@@ -175,9 +177,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
175
177
|
version: '0'
|
176
178
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
177
179
|
requirements:
|
178
|
-
- - "
|
180
|
+
- - ">="
|
179
181
|
- !ruby/object:Gem::Version
|
180
|
-
version:
|
182
|
+
version: '0'
|
181
183
|
requirements: []
|
182
184
|
rubyforge_project:
|
183
185
|
rubygems_version: 2.7.6
|