activerecord-hierarchical_query 1.0.1 → 1.3.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 +71 -49
- data/lib/active_record/hierarchical_query/cte/columns.rb +17 -3
- 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/lib/arel/nodes/postgresql.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 +41 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b5166c41ef62af29c1883f5b6e3f3447ba422bf76bae1bf5672f1f4991bbda08
|
4
|
+
data.tar.gz: 519b6c33c67c1b3e69578ca7abf693f1076a69f9d7f45cec5b800b954f17c7a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21208d283a34594e442d19023db12e2d8cf3f79b04a55c397ce1dd97b5ccc6990db05a799b1a71a85410d5c2a905b7ba5e3791cbcb83e34611d138afe8c044d9
|
7
|
+
data.tar.gz: e54b02481e06962334aa9627c1fa1971dd92960aa5d2247dd4172a82f59738bcb5d10cafbc65efe8e8dcf373d81da7e4544e3fc0c938937fd33e343f7e672cd7
|
data/README.md
CHANGED
@@ -3,12 +3,32 @@
|
|
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.0, < 6.1
|
17
|
+
- PostgreSQL >= 8.4
|
18
|
+
- Postgres Gem >= 0.21, < 1.2
|
19
|
+
|
20
|
+
Note that though PostgresSQL 8.4 and up should work, this library
|
21
|
+
is tested on PostgresSQL 10.5.
|
22
|
+
|
23
|
+
### Rails Version
|
24
|
+
|
25
|
+
**Rails 4 support has ended.**
|
26
|
+
|
27
|
+
If you have trouble with Rails 5.1 or 5.0, try upgrading to Rails 5.2
|
28
|
+
first. Rails 6 should work, but please report issues immediately as
|
29
|
+
support is recent.
|
30
|
+
|
31
|
+
## In a nutshell
|
12
32
|
|
13
33
|
### Traverse trees
|
14
34
|
|
@@ -59,25 +79,12 @@ records = Category.join_recursive do |query|
|
|
59
79
|
.connect_by(parent_id: :id)
|
60
80
|
end.order('depth ASC')
|
61
81
|
|
62
|
-
#
|
82
|
+
# returns a regular ActiveRecord::Relation instance
|
83
|
+
# so methods like `pluck` all work as expected.
|
84
|
+
|
63
85
|
crumbs = records.pluck(:name).join(' / ')
|
64
86
|
```
|
65
87
|
|
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
88
|
## Installation
|
82
89
|
|
83
90
|
Add this line to your application's Gemfile:
|
@@ -106,12 +113,12 @@ Alternatively, the require can be placed in the `Gemfile`:
|
|
106
113
|
gem 'activerecord-hierarchical_query', require: 'active_record/hierarchical_query'
|
107
114
|
```
|
108
115
|
|
109
|
-
|
110
116
|
## Usage
|
111
117
|
|
112
|
-
Let's say you've got an ActiveRecord model `Category` with
|
113
|
-
and `name`. You can traverse nodes
|
114
|
-
|
118
|
+
Let's say you've got an ActiveRecord model `Category` with
|
119
|
+
attributes `id`, `parent_id` and `name`. You can traverse nodes
|
120
|
+
recursively starting from root rows connected by `parent_id`
|
121
|
+
column ordered by `name`:
|
115
122
|
|
116
123
|
```ruby
|
117
124
|
Category.join_recursive do
|
@@ -123,13 +130,15 @@ end
|
|
123
130
|
|
124
131
|
Hierarchical queries consist of these important clauses:
|
125
132
|
|
126
|
-
|
133
|
+
- **START WITH** clause
|
127
134
|
|
128
135
|
This clause specifies the root row(s) of the hierarchy.
|
129
|
-
|
136
|
+
|
137
|
+
- **CONNECT BY** clause
|
130
138
|
|
131
139
|
This clause specifies relationship between parent rows and child rows of the hierarchy.
|
132
|
-
|
140
|
+
|
141
|
+
- **ORDER SIBLINGS** clause
|
133
142
|
|
134
143
|
This clause specifies an order of rows in which they appear on each hierarchy level.
|
135
144
|
|
@@ -137,14 +146,16 @@ These terms are borrowed from [Oracle hierarchical queries syntax](http://docs.o
|
|
137
146
|
|
138
147
|
Hierarchical queries are processed as follows:
|
139
148
|
|
140
|
-
|
149
|
+
- First, root rows are selected -- those rows that satisfy `START WITH` condition in
|
141
150
|
order specified by `ORDER SIBLINGS` clause. In example above it's specified by
|
142
151
|
statements `query.start_with(parent_id: nil)` and `query.order_siblings(:name)`.
|
143
|
-
|
152
|
+
|
153
|
+
- Second, child rows for each root rows are selected. Each child row must satisfy
|
144
154
|
condition specified by `CONNECT BY` clause with respect to one of the root rows
|
145
155
|
(`query.connect_by(id: :parent_id)` in example above). Order of child rows is
|
146
156
|
also specified by `ORDER SIBLINGS` clause.
|
147
|
-
|
157
|
+
|
158
|
+
- Successive generations of child rows are selected with respect to `CONNECT BY` clause.
|
148
159
|
First the children of each row selected in step 2 selected, then the children of those
|
149
160
|
children and so on.
|
150
161
|
|
@@ -201,7 +212,8 @@ Category.join_recursive do
|
|
201
212
|
end
|
202
213
|
```
|
203
214
|
|
204
|
-
You can even refer to parent table, just don't forget to include
|
215
|
+
You can even refer to parent table, just don't forget to include
|
216
|
+
columns in `SELECT` clause!
|
205
217
|
|
206
218
|
```ruby
|
207
219
|
Category.join_recursive do |query|
|
@@ -222,8 +234,9 @@ end
|
|
222
234
|
|
223
235
|
### NOCYCLE
|
224
236
|
|
225
|
-
Recursive query will loop if hierarchy contains cycles (your
|
226
|
-
`NOCYCLE` clause, which is turned off by
|
237
|
+
Recursive query will loop if hierarchy contains cycles (your
|
238
|
+
graph is not acyclic). `NOCYCLE` clause, which is turned off by
|
239
|
+
default, could prevent it.
|
227
240
|
|
228
241
|
Loop example:
|
229
242
|
|
@@ -235,7 +248,8 @@ node_1.parent = node_2
|
|
235
248
|
node_1.save
|
236
249
|
```
|
237
250
|
|
238
|
-
`node_1` and `node_2` now link to each other, so following
|
251
|
+
`node_1` and `node_2` now link to each other, so the following
|
252
|
+
query will not terminate:
|
239
253
|
|
240
254
|
```ruby
|
241
255
|
Category.join_recursive do |query|
|
@@ -255,8 +269,11 @@ end
|
|
255
269
|
```
|
256
270
|
|
257
271
|
## DISTINCT
|
258
|
-
|
259
|
-
|
272
|
+
|
273
|
+
By default, the union term in the Common Table Expression uses a
|
274
|
+
`UNION ALL`. If you want to `SELECT DISTINCT` CTE values, add a
|
275
|
+
query option for `distinct`:
|
276
|
+
|
260
277
|
```ruby
|
261
278
|
Category.join_recursive do |query|
|
262
279
|
query.connect_by(id: :parent_id)
|
@@ -265,7 +282,9 @@ Category.join_recursive do |query|
|
|
265
282
|
end
|
266
283
|
```
|
267
284
|
|
268
|
-
If you want to join CTE terms by `UNION DISTINCT`, pass an option
|
285
|
+
If you want to join CTE terms by `UNION DISTINCT`, pass an option
|
286
|
+
to `join_recursive`:
|
287
|
+
|
269
288
|
```ruby
|
270
289
|
Category.join_recursive(union_type: :distinct) do |query|
|
271
290
|
query.connect_by(id: :parent_id)
|
@@ -291,7 +310,7 @@ Category.join_recursive do |query|
|
|
291
310
|
end
|
292
311
|
```
|
293
312
|
|
294
|
-
|
313
|
+
Would generate following SQL:
|
295
314
|
|
296
315
|
```sql
|
297
316
|
SELECT "categories".*
|
@@ -324,27 +343,30 @@ FROM "categories" INNER JOIN (
|
|
324
343
|
ORDER BY "categories__recursive"."__order_column" ASC
|
325
344
|
```
|
326
345
|
|
327
|
-
If you want to use a `LEFT OUTER JOIN` instead of an `INNER JOIN`,
|
346
|
+
If you want to use a `LEFT OUTER JOIN` instead of an `INNER JOIN`,
|
347
|
+
add a query option for `outer_join_hierarchical`. This
|
348
|
+
option allows the query to return non-hierarchical entries:
|
349
|
+
|
328
350
|
```ruby
|
329
351
|
.join_recursive(outer_join_hierarchical: true)
|
330
352
|
```
|
331
353
|
|
332
|
-
If, when joining the recursive view to the main table, you want
|
354
|
+
If, when joining the recursive view to the main table, you want
|
355
|
+
to change the foreign_key on the recursive view from the primary
|
356
|
+
key of the main table to another column:
|
357
|
+
|
333
358
|
```ruby
|
334
|
-
.join_recursive(foreign_key: another_column)
|
359
|
+
.join_recursive(foreign_key: another_column)
|
335
360
|
```
|
336
361
|
|
337
362
|
## Related resources
|
338
363
|
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
364
|
+
- [About hierarchical queries (Wikipedia)](http://en.wikipedia.org/wiki/Hierarchical_and_recursive_queries_in_SQL)
|
365
|
+
- [Hierarchical queries in Oracle](http://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm)
|
366
|
+
- [Recursive queries in PostgreSQL](http://www.postgresql.org/docs/9.3/static/queries-with.html)
|
367
|
+
- [Using Recursive SQL with ActiveRecord trees](http://hashrocket.com/blog/posts/recursive-sql-in-activerecord)
|
343
368
|
|
344
369
|
## Contributing
|
345
370
|
|
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
|
371
|
+
Read through the short
|
372
|
+
[contributing guide](https://github.com/take-five/activerecord-hierarchical_query/blob/master/CONTRIBUTING.md).
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'arel/visitors/depth_first'
|
2
|
-
|
3
1
|
module ActiveRecord
|
4
2
|
module HierarchicalQuery
|
5
3
|
module CTE
|
@@ -18,7 +16,23 @@ module ActiveRecord
|
|
18
16
|
|
19
17
|
private
|
20
18
|
def connect_by_columns
|
21
|
-
|
19
|
+
columns = []
|
20
|
+
traverse(@query.join_conditions) do |node|
|
21
|
+
columns << node.name.to_s if node.is_a?(Arel::Attributes::Attribute)
|
22
|
+
end
|
23
|
+
columns
|
24
|
+
end
|
25
|
+
|
26
|
+
def traverse(ast, &blck)
|
27
|
+
if ast && ast.respond_to?(:left) && ast.left
|
28
|
+
traverse(ast.left, &blck)
|
29
|
+
end
|
30
|
+
|
31
|
+
if ast && ast.respond_to?(:right) && ast.right
|
32
|
+
traverse(ast.right, &blck)
|
33
|
+
end
|
34
|
+
|
35
|
+
yield ast
|
22
36
|
end
|
23
37
|
end
|
24
38
|
end
|
@@ -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
|
@@ -25,7 +25,7 @@ module Arel
|
|
25
25
|
ARRAY_CLOSING = ']'.freeze
|
26
26
|
ARRAY_CONCAT = '||'.freeze
|
27
27
|
|
28
|
-
if Arel::VERSION < '6.0.0'
|
28
|
+
if Gem::Version.new(Arel::VERSION) < Gem::Version.new('6.0.0')
|
29
29
|
def visit_Arel_Nodes_PostgresArray o, *a
|
30
30
|
"#{ARRAY_OPENING}#{visit o.values, *a}#{ARRAY_CLOSING}"
|
31
31
|
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.3.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: 2021-05-26 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: '
|
23
|
+
version: '6.2'
|
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: '
|
33
|
+
version: '6.2'
|
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.3'
|
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.3'
|
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: []
|
@@ -147,8 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
169
|
- !ruby/object:Gem::Version
|
148
170
|
version: '0'
|
149
171
|
requirements: []
|
150
|
-
|
151
|
-
rubygems_version: 2.4.8
|
172
|
+
rubygems_version: 3.2.15
|
152
173
|
signing_key:
|
153
174
|
specification_version: 4
|
154
175
|
summary: Recursively traverse trees using a single SQL query
|