activerecord-hierarchical_query 1.0.1 → 1.1.0
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/README.md +69 -39
- data/lib/active_record/hierarchical_query/cte/non_recursive_term.rb +8 -2
- data/lib/active_record/hierarchical_query/cte/recursive_term.rb +8 -2
- data/lib/active_record/hierarchical_query/cte/union_term.rb +10 -2
- data/lib/active_record/hierarchical_query/join_builder.rb +27 -6
- data/lib/active_record/hierarchical_query/version.rb +1 -1
- data/spec/active_record/hierarchical_query_spec.rb +12 -0
- data/spec/spec_helper.rb +24 -9
- data/spec/support/models.rb +10 -0
- metadata +39 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 31640e2b4355e1204bc3ff3c233124de13269b864b4b55a893c528f23bfac6dc
|
4
|
+
data.tar.gz: c6a07c2b90fc9121d62cdf4be640f87abbc841e8055cdb0fecdef90999885e26
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b6151f2d1ca6cbaa9c0a85ab5fd9e1242a4bdf8bbeac17634b887d7084ea0fc39fd980f5052d10a8c76dd4df6d05b3160007fee707a162b5d1fb3af8d65ce58
|
7
|
+
data.tar.gz: 2b686e08d2ec2189952f6a76c8e78578c75a10cd8410a2ec4872ab5372c547a57dd9b6b63616b9fd0567713ad99254d5e1a8759e5e1ac9d3dd2fee9c277626b3
|
data/README.md
CHANGED
@@ -3,12 +3,42 @@
|
|
3
3
|
[](https://travis-ci.org/take-five/activerecord-hierarchical_query)
|
4
4
|
[](https://codeclimate.com/github/take-five/activerecord-hierarchical_query)
|
5
5
|
[](https://coveralls.io/r/take-five/activerecord-hierarchical_query)
|
6
|
-
[](https://gemnasium.com/take-five/activerecord-hierarchical_query)
|
7
6
|
[](http://badge.fury.io/rb/activerecord-hierarchical_query)
|
8
7
|
|
9
|
-
Create hierarchical queries using simple DSL, recursively
|
8
|
+
Create hierarchical queries using simple DSL, recursively
|
9
|
+
traverse trees using single SQL query.
|
10
10
|
|
11
|
-
If a table contains hierarchical data, then you can select rows
|
11
|
+
If a table contains hierarchical data, then you can select rows
|
12
|
+
in hierarchical order using hierarchical query builder.
|
13
|
+
|
14
|
+
## Requirements
|
15
|
+
|
16
|
+
* ActiveRecord ~> 5.2
|
17
|
+
* PostgreSQL >= 8.4
|
18
|
+
|
19
|
+
Note that though PostgresSQL 8.4 and up should work, this library
|
20
|
+
is tested on PostgresSQL 10.5.
|
21
|
+
|
22
|
+
### Rails Version
|
23
|
+
|
24
|
+
**Rails 3 support has ended.**
|
25
|
+
|
26
|
+
**Support for Rails 4 is limited to review of security related
|
27
|
+
pull requests that include tests.** EOL for Rails 4 is when
|
28
|
+
Rails 6 comes out.
|
29
|
+
|
30
|
+
Rails 5 is supported on the `rails-5` branch and through gem
|
31
|
+
versions `>= 1.0.0` on rubygems.org. This branch will soon
|
32
|
+
replace master. If you have trouble with Rails 5.1 or 5.0,
|
33
|
+
upgrade to Rails 5.2 and install the latest version.
|
34
|
+
|
35
|
+
Now that @zachaysan is the new primary maintainer of this
|
36
|
+
project, support for laggard versions of Rails is going to be
|
37
|
+
minimal. Security updates will be accepted, but due to structural
|
38
|
+
changes in Rails core it's no longer possible to easily support
|
39
|
+
former versions of Rails.
|
40
|
+
|
41
|
+
## In a nutshell
|
12
42
|
|
13
43
|
### Traverse trees
|
14
44
|
|
@@ -59,25 +89,12 @@ records = Category.join_recursive do |query|
|
|
59
89
|
.connect_by(parent_id: :id)
|
60
90
|
end.order('depth ASC')
|
61
91
|
|
62
|
-
#
|
92
|
+
# returns a regular ActiveRecord::Relation instance
|
93
|
+
# so methods like `pluck` all work as expected.
|
94
|
+
|
63
95
|
crumbs = records.pluck(:name).join(' / ')
|
64
96
|
```
|
65
97
|
|
66
|
-
## Requirements
|
67
|
-
|
68
|
-
* ActiveRecord >= 3.1.0
|
69
|
-
* PostgreSQL >= 8.4
|
70
|
-
|
71
|
-
## Rails 5
|
72
|
-
|
73
|
-
Rails 5 is supported on the `rails-5` branch and through gem versions
|
74
|
-
`>= 1.0.0` on rubygems.org. The Rails branch is intended to
|
75
|
-
follow minor Rails releases (currently 5.1), but it should be
|
76
|
-
compatible with 5.0 as well. If you have trouble try upgrading Rails
|
77
|
-
first. Tag @zachaysan with in a GitHub issue if the latest version
|
78
|
-
of Rails is not supported or if there are reproducable problems on
|
79
|
-
the latest minor version of Rails 5.
|
80
|
-
|
81
98
|
## Installation
|
82
99
|
|
83
100
|
Add this line to your application's Gemfile:
|
@@ -106,12 +123,12 @@ Alternatively, the require can be placed in the `Gemfile`:
|
|
106
123
|
gem 'activerecord-hierarchical_query', require: 'active_record/hierarchical_query'
|
107
124
|
```
|
108
125
|
|
109
|
-
|
110
126
|
## Usage
|
111
127
|
|
112
|
-
Let's say you've got an ActiveRecord model `Category` with
|
113
|
-
and `name`. You can traverse nodes
|
114
|
-
|
128
|
+
Let's say you've got an ActiveRecord model `Category` with
|
129
|
+
attributes `id`, `parent_id` and `name`. You can traverse nodes
|
130
|
+
recursively starting from root rows connected by `parent_id`
|
131
|
+
column ordered by `name`:
|
115
132
|
|
116
133
|
```ruby
|
117
134
|
Category.join_recursive do
|
@@ -140,10 +157,12 @@ Hierarchical queries are processed as follows:
|
|
140
157
|
* First, root rows are selected -- those rows that satisfy `START WITH` condition in
|
141
158
|
order specified by `ORDER SIBLINGS` clause. In example above it's specified by
|
142
159
|
statements `query.start_with(parent_id: nil)` and `query.order_siblings(:name)`.
|
160
|
+
|
143
161
|
* Second, child rows for each root rows are selected. Each child row must satisfy
|
144
162
|
condition specified by `CONNECT BY` clause with respect to one of the root rows
|
145
163
|
(`query.connect_by(id: :parent_id)` in example above). Order of child rows is
|
146
164
|
also specified by `ORDER SIBLINGS` clause.
|
165
|
+
|
147
166
|
* Successive generations of child rows are selected with respect to `CONNECT BY` clause.
|
148
167
|
First the children of each row selected in step 2 selected, then the children of those
|
149
168
|
children and so on.
|
@@ -201,7 +220,8 @@ Category.join_recursive do
|
|
201
220
|
end
|
202
221
|
```
|
203
222
|
|
204
|
-
You can even refer to parent table, just don't forget to include
|
223
|
+
You can even refer to parent table, just don't forget to include
|
224
|
+
columns in `SELECT` clause!
|
205
225
|
|
206
226
|
```ruby
|
207
227
|
Category.join_recursive do |query|
|
@@ -222,8 +242,9 @@ end
|
|
222
242
|
|
223
243
|
### NOCYCLE
|
224
244
|
|
225
|
-
Recursive query will loop if hierarchy contains cycles (your
|
226
|
-
`NOCYCLE` clause, which is turned off by
|
245
|
+
Recursive query will loop if hierarchy contains cycles (your
|
246
|
+
graph is not acyclic). `NOCYCLE` clause, which is turned off by
|
247
|
+
default, could prevent it.
|
227
248
|
|
228
249
|
Loop example:
|
229
250
|
|
@@ -235,7 +256,8 @@ node_1.parent = node_2
|
|
235
256
|
node_1.save
|
236
257
|
```
|
237
258
|
|
238
|
-
`node_1` and `node_2` now link to each other, so following
|
259
|
+
`node_1` and `node_2` now link to each other, so the following
|
260
|
+
query will not terminate:
|
239
261
|
|
240
262
|
```ruby
|
241
263
|
Category.join_recursive do |query|
|
@@ -255,8 +277,11 @@ end
|
|
255
277
|
```
|
256
278
|
|
257
279
|
## DISTINCT
|
258
|
-
|
259
|
-
|
280
|
+
|
281
|
+
By default, the union term in the Common Table Expression uses a
|
282
|
+
`UNION ALL`. If you want to `SELECT DISTINCT` CTE values, add a
|
283
|
+
query option for `distinct`:
|
284
|
+
|
260
285
|
```ruby
|
261
286
|
Category.join_recursive do |query|
|
262
287
|
query.connect_by(id: :parent_id)
|
@@ -265,7 +290,9 @@ Category.join_recursive do |query|
|
|
265
290
|
end
|
266
291
|
```
|
267
292
|
|
268
|
-
If you want to join CTE terms by `UNION DISTINCT`, pass an option
|
293
|
+
If you want to join CTE terms by `UNION DISTINCT`, pass an option
|
294
|
+
to `join_recursive`:
|
295
|
+
|
269
296
|
```ruby
|
270
297
|
Category.join_recursive(union_type: :distinct) do |query|
|
271
298
|
query.connect_by(id: :parent_id)
|
@@ -291,7 +318,7 @@ Category.join_recursive do |query|
|
|
291
318
|
end
|
292
319
|
```
|
293
320
|
|
294
|
-
|
321
|
+
Would generate following SQL:
|
295
322
|
|
296
323
|
```sql
|
297
324
|
SELECT "categories".*
|
@@ -324,14 +351,20 @@ FROM "categories" INNER JOIN (
|
|
324
351
|
ORDER BY "categories__recursive"."__order_column" ASC
|
325
352
|
```
|
326
353
|
|
327
|
-
If you want to use a `LEFT OUTER JOIN` instead of an `INNER JOIN`,
|
354
|
+
If you want to use a `LEFT OUTER JOIN` instead of an `INNER JOIN`,
|
355
|
+
add a query option for `outer_join_hierarchical`. This
|
356
|
+
option allows the query to return non-hierarchical entries:
|
357
|
+
|
328
358
|
```ruby
|
329
359
|
.join_recursive(outer_join_hierarchical: true)
|
330
360
|
```
|
331
361
|
|
332
|
-
If, when joining the recursive view to the main table, you want
|
362
|
+
If, when joining the recursive view to the main table, you want
|
363
|
+
to change the foreign_key on the recursive view from the primary
|
364
|
+
key of the main table to another column:
|
365
|
+
|
333
366
|
```ruby
|
334
|
-
.join_recursive(foreign_key: another_column)
|
367
|
+
.join_recursive(foreign_key: another_column)
|
335
368
|
```
|
336
369
|
|
337
370
|
## Related resources
|
@@ -343,8 +376,5 @@ If, when joining the recursive view to the main table, you want to change the fo
|
|
343
376
|
|
344
377
|
## Contributing
|
345
378
|
|
346
|
-
|
347
|
-
|
348
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
349
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
350
|
-
5. Create new Pull Request
|
379
|
+
Read through the short
|
380
|
+
[contributing guide](https://github.com/take-five/activerecord-hierarchical_query/blob/master/CONTRIBUTING.md).
|
@@ -14,8 +14,14 @@ module ActiveRecord
|
|
14
14
|
@builder = builder
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
if ActiveRecord.version < Gem::Version.new("5.2")
|
18
|
+
def bind_values
|
19
|
+
scope.bound_attributes
|
20
|
+
end
|
21
|
+
else
|
22
|
+
def bind_values
|
23
|
+
scope.values || {}
|
24
|
+
end
|
19
25
|
end
|
20
26
|
|
21
27
|
def arel
|
@@ -12,8 +12,14 @@ module ActiveRecord
|
|
12
12
|
@builder = builder
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
if ActiveRecord.version < Gem::Version.new("5.2")
|
16
|
+
def bind_values
|
17
|
+
scope.bound_attributes
|
18
|
+
end
|
19
|
+
else
|
20
|
+
def bind_values
|
21
|
+
scope.values || {}
|
22
|
+
end
|
17
23
|
end
|
18
24
|
|
19
25
|
def arel
|
@@ -11,8 +11,16 @@ module ActiveRecord
|
|
11
11
|
@union_type = options.fetch(:union_type, :all)
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
if ActiveRecord.version < Gem::Version.new("5.2")
|
15
|
+
def bind_values
|
16
|
+
non_recursive_term.bind_values + recursive_term.bind_values
|
17
|
+
end
|
18
|
+
else
|
19
|
+
def bind_values
|
20
|
+
non_recursive_term
|
21
|
+
.bind_values
|
22
|
+
.merge recursive_term.bind_values
|
23
|
+
end
|
16
24
|
end
|
17
25
|
|
18
26
|
def arel
|
@@ -23,13 +23,21 @@ module ActiveRecord
|
|
23
23
|
|
24
24
|
relation = relation.joins(joined_arel_node)
|
25
25
|
|
26
|
-
|
26
|
+
return relation unless ActiveRecord.version < Gem::Version.new("5.2")
|
27
|
+
|
27
28
|
relation.bind_values += bind_values
|
28
29
|
|
29
30
|
relation
|
30
31
|
end
|
31
32
|
|
32
33
|
private
|
34
|
+
|
35
|
+
if ActiveRecord.version < Gem::Version.new("5.2")
|
36
|
+
def bind_values
|
37
|
+
@builder.bind_values
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
33
41
|
def joined_arel_node
|
34
42
|
@options[:outer_join_hierarchical] == true ? outer_join : inner_join
|
35
43
|
end
|
@@ -70,10 +78,6 @@ module ActiveRecord
|
|
70
78
|
custom_foreign_key ? @alias[custom_foreign_key] : @alias[@query.klass.primary_key]
|
71
79
|
end
|
72
80
|
|
73
|
-
def bind_values
|
74
|
-
@builder.bind_values
|
75
|
-
end
|
76
|
-
|
77
81
|
def ordered?
|
78
82
|
@query.orderings.any?
|
79
83
|
end
|
@@ -84,12 +88,29 @@ module ActiveRecord
|
|
84
88
|
|
85
89
|
# This node is required to support joins to aliased Arel nodes
|
86
90
|
class SubqueryAlias < Arel::Nodes::As
|
91
|
+
|
87
92
|
attr_reader :table_name
|
88
93
|
|
94
|
+
unless method_defined? :name
|
95
|
+
alias_method :name, :table_name
|
96
|
+
end
|
97
|
+
|
89
98
|
def initialize(subquery, alias_node)
|
90
99
|
super
|
91
|
-
|
100
|
+
|
101
|
+
@table_name = alias_node.try :name
|
102
|
+
|
103
|
+
return unless alias_node.respond_to? :left
|
104
|
+
|
105
|
+
aliased_name = alias_node.left.relation.name
|
106
|
+
return if @table_name == aliased_name
|
107
|
+
|
108
|
+
# Defensive coding; this shouldn't happen unless the
|
109
|
+
# Rails team does a change to how Arel works.
|
110
|
+
message = "Unexpected alias name mismatch"
|
111
|
+
raise RuntimeError, message
|
92
112
|
end
|
113
|
+
|
93
114
|
end
|
94
115
|
end
|
95
116
|
end
|
@@ -59,6 +59,18 @@ describe ActiveRecord::HierarchicalQuery do
|
|
59
59
|
end
|
60
60
|
).to include root, child_1, child_2, child_3, child_4, child_5
|
61
61
|
end
|
62
|
+
|
63
|
+
it 'handles Arel::Nodes::As name delegation' do
|
64
|
+
expected_array = \
|
65
|
+
klass.join_recursive do
|
66
|
+
connect_by { |parent, child| parent[:id].eq child[:parent_id] }
|
67
|
+
end
|
68
|
+
|
69
|
+
expect(
|
70
|
+
child_5.alias_node_query
|
71
|
+
).to match_array expected_array
|
72
|
+
end
|
73
|
+
|
62
74
|
end
|
63
75
|
|
64
76
|
describe 'START WITH clause' do
|
data/spec/spec_helper.rb
CHANGED
@@ -2,9 +2,14 @@
|
|
2
2
|
require 'pathname'
|
3
3
|
require 'logger'
|
4
4
|
|
5
|
+
begin
|
6
|
+
require 'pry'
|
7
|
+
rescue LoadError
|
8
|
+
end
|
9
|
+
|
5
10
|
ENV['TZ'] = 'UTC'
|
6
11
|
|
7
|
-
SPEC_ROOT = Pathname.new(File.dirname(__FILE__))
|
12
|
+
SPEC_ROOT = Pathname.new(File.dirname(__FILE__)) unless defined? SPEC_ROOT
|
8
13
|
|
9
14
|
require 'bundler'
|
10
15
|
Bundler.setup(:default, ENV['TRAVIS'] ? :travis : :local)
|
@@ -15,25 +20,35 @@ require 'active_record'
|
|
15
20
|
|
16
21
|
ActiveRecord::Base.configurations = YAML.load(SPEC_ROOT.join('database.yml').read)
|
17
22
|
ActiveRecord::Base.establish_connection(:pg)
|
23
|
+
|
18
24
|
ActiveRecord::Base.logger = Logger.new(ENV['DEBUG'] ? $stderr : '/dev/null')
|
19
25
|
ActiveRecord::Base.logger.formatter = proc do |severity, datetime, progname, msg|
|
20
26
|
"#{datetime.strftime('%H:%M:%S.%L')}: #{msg}\n"
|
21
27
|
end
|
22
28
|
|
23
|
-
|
29
|
+
begin
|
30
|
+
load SPEC_ROOT.join('schema.rb')
|
31
|
+
rescue ActiveRecord::NoDatabaseError
|
32
|
+
bold = "\033[1m"
|
33
|
+
red = "\033[31m"
|
34
|
+
reset = "\033[0m"
|
35
|
+
|
36
|
+
puts ""
|
37
|
+
puts bold + red + "Database missing." + reset
|
38
|
+
puts "If you have #{bold}sudo#{reset}, run the below " +
|
39
|
+
"(ignore any role creation errors)."
|
40
|
+
puts ""
|
41
|
+
puts bold + "rake db:create" + reset
|
42
|
+
puts ""
|
43
|
+
exit
|
44
|
+
end
|
45
|
+
|
24
46
|
require SPEC_ROOT.join('support', 'models').to_s
|
25
47
|
|
26
48
|
DatabaseCleaner.strategy = :transaction
|
27
49
|
|
28
|
-
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
29
50
|
RSpec.configure do |config|
|
30
|
-
config.run_all_when_everything_filtered = true
|
31
|
-
config.filter_run :focus
|
32
51
|
|
33
|
-
# Run specs in random order to surface order dependencies. If you find an
|
34
|
-
# order dependency and want to debug it, you can fix the order by providing
|
35
|
-
# the seed, which is printed after each run.
|
36
|
-
# --seed 1234
|
37
52
|
config.order = 'random'
|
38
53
|
|
39
54
|
config.around(:each) do |example|
|
data/spec/support/models.rb
CHANGED
@@ -37,6 +37,16 @@ class Category < ActiveRecord::Base
|
|
37
37
|
def ancestors
|
38
38
|
parent ? parent.ancestors + [parent] : []
|
39
39
|
end
|
40
|
+
|
41
|
+
# Arel::Nodes::As delegates name to the left relation
|
42
|
+
def alias_node_query
|
43
|
+
Category.left_outer_joins(:articles)
|
44
|
+
.join_recursive do |query|
|
45
|
+
query
|
46
|
+
.connect_by(id: :parent_id)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
40
50
|
end
|
41
51
|
|
42
52
|
class Article < ActiveRecord::Base
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-hierarchical_query
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexei Mikhailov
|
8
|
+
- Zach Aysan
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2018-09-22 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: activerecord
|
@@ -16,93 +17,114 @@ dependencies:
|
|
16
17
|
requirements:
|
17
18
|
- - ">="
|
18
19
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
20
|
+
version: '5.0'
|
20
21
|
- - "<"
|
21
22
|
- !ruby/object:Gem::Version
|
22
|
-
version: '5.
|
23
|
+
version: '5.3'
|
23
24
|
type: :runtime
|
24
25
|
prerelease: false
|
25
26
|
version_requirements: !ruby/object:Gem::Requirement
|
26
27
|
requirements:
|
27
28
|
- - ">="
|
28
29
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
30
|
+
version: '5.0'
|
30
31
|
- - "<"
|
31
32
|
- !ruby/object:Gem::Version
|
32
|
-
version: '5.
|
33
|
+
version: '5.3'
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: pg
|
36
|
+
requirement: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.21'
|
41
|
+
- - "<"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '1.2'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0.21'
|
51
|
+
- - "<"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.2'
|
33
54
|
- !ruby/object:Gem::Dependency
|
34
55
|
name: bundler
|
35
56
|
requirement: !ruby/object:Gem::Requirement
|
36
57
|
requirements:
|
37
58
|
- - "~>"
|
38
59
|
- !ruby/object:Gem::Version
|
39
|
-
version: '1.
|
60
|
+
version: '1.16'
|
40
61
|
type: :development
|
41
62
|
prerelease: false
|
42
63
|
version_requirements: !ruby/object:Gem::Requirement
|
43
64
|
requirements:
|
44
65
|
- - "~>"
|
45
66
|
- !ruby/object:Gem::Version
|
46
|
-
version: '1.
|
67
|
+
version: '1.16'
|
47
68
|
- !ruby/object:Gem::Dependency
|
48
69
|
name: rake
|
49
70
|
requirement: !ruby/object:Gem::Requirement
|
50
71
|
requirements:
|
51
72
|
- - "~>"
|
52
73
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
74
|
+
version: '12.3'
|
54
75
|
type: :development
|
55
76
|
prerelease: false
|
56
77
|
version_requirements: !ruby/object:Gem::Requirement
|
57
78
|
requirements:
|
58
79
|
- - "~>"
|
59
80
|
- !ruby/object:Gem::Version
|
60
|
-
version:
|
81
|
+
version: '12.3'
|
61
82
|
- !ruby/object:Gem::Dependency
|
62
83
|
name: rspec
|
63
84
|
requirement: !ruby/object:Gem::Requirement
|
64
85
|
requirements:
|
65
86
|
- - "~>"
|
66
87
|
- !ruby/object:Gem::Version
|
67
|
-
version: 3.
|
88
|
+
version: '3.8'
|
68
89
|
type: :development
|
69
90
|
prerelease: false
|
70
91
|
version_requirements: !ruby/object:Gem::Requirement
|
71
92
|
requirements:
|
72
93
|
- - "~>"
|
73
94
|
- !ruby/object:Gem::Version
|
74
|
-
version: 3.
|
95
|
+
version: '3.8'
|
75
96
|
- !ruby/object:Gem::Dependency
|
76
97
|
name: database_cleaner
|
77
98
|
requirement: !ruby/object:Gem::Requirement
|
78
99
|
requirements:
|
79
100
|
- - "~>"
|
80
101
|
- !ruby/object:Gem::Version
|
81
|
-
version: 1.
|
102
|
+
version: '1.7'
|
82
103
|
type: :development
|
83
104
|
prerelease: false
|
84
105
|
version_requirements: !ruby/object:Gem::Requirement
|
85
106
|
requirements:
|
86
107
|
- - "~>"
|
87
108
|
- !ruby/object:Gem::Version
|
88
|
-
version: 1.
|
109
|
+
version: '1.7'
|
89
110
|
- !ruby/object:Gem::Dependency
|
90
111
|
name: simplecov
|
91
112
|
requirement: !ruby/object:Gem::Requirement
|
92
113
|
requirements:
|
93
114
|
- - "~>"
|
94
115
|
- !ruby/object:Gem::Version
|
95
|
-
version: 0.
|
116
|
+
version: '0.16'
|
96
117
|
type: :development
|
97
118
|
prerelease: false
|
98
119
|
version_requirements: !ruby/object:Gem::Requirement
|
99
120
|
requirements:
|
100
121
|
- - "~>"
|
101
122
|
- !ruby/object:Gem::Version
|
102
|
-
version: 0.
|
123
|
+
version: '0.16'
|
103
124
|
description:
|
104
125
|
email:
|
105
126
|
- amikhailov83@gmail.com
|
127
|
+
- zachaysan@gmail.com
|
106
128
|
executables: []
|
107
129
|
extensions: []
|
108
130
|
extra_rdoc_files: []
|
@@ -148,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
170
|
version: '0'
|
149
171
|
requirements: []
|
150
172
|
rubyforge_project:
|
151
|
-
rubygems_version: 2.
|
173
|
+
rubygems_version: 2.7.7
|
152
174
|
signing_key:
|
153
175
|
specification_version: 4
|
154
176
|
summary: Recursively traverse trees using a single SQL query
|