activerecord-hierarchical_query 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://travis-ci.org/take-five/activerecord-hierarchical_query.png?branch=master)](https://travis-ci.org/take-five/activerecord-hierarchical_query)
|
4
4
|
[![Code Climate](https://codeclimate.com/github/take-five/activerecord-hierarchical_query.png)](https://codeclimate.com/github/take-five/activerecord-hierarchical_query)
|
5
5
|
[![Coverage Status](https://coveralls.io/repos/take-five/activerecord-hierarchical_query/badge.png)](https://coveralls.io/r/take-five/activerecord-hierarchical_query)
|
6
|
-
[![Dependency Status](https://gemnasium.com/take-five/activerecord-hierarchical_query.png)](https://gemnasium.com/take-five/activerecord-hierarchical_query)
|
7
6
|
[![Gem Version](https://badge.fury.io/rb/activerecord-hierarchical_query.png)](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
|