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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 81984079ce907a96ab19520c8ecd77bcf587b0b4
4
- data.tar.gz: a75cf7a24893407ab3be1c30289fdb3d1e6d926a
2
+ SHA256:
3
+ metadata.gz: b5166c41ef62af29c1883f5b6e3f3447ba422bf76bae1bf5672f1f4991bbda08
4
+ data.tar.gz: 519b6c33c67c1b3e69578ca7abf693f1076a69f9d7f45cec5b800b954f17c7a2
5
5
  SHA512:
6
- metadata.gz: a5de9642594d03716e3ee6cda1ee023e2362c2608eb06d50321611eab31e09b7b7d01f03ddecd062d38dd0579bf87002625a21d2e0230e6a582ea121cb6bdb3e
7
- data.tar.gz: 968afb8c7471b36a6e2029f5f8022a325e521a1808fbace12365be16c83aa360785c9009ee566403c9b7eb0a14ed2c58945f1ca51464c6b85ef612b28186248c
6
+ metadata.gz: 21208d283a34594e442d19023db12e2d8cf3f79b04a55c397ce1dd97b5ccc6990db05a799b1a71a85410d5c2a905b7ba5e3791cbcb83e34611d138afe8c044d9
7
+ data.tar.gz: e54b02481e06962334aa9627c1fa1971dd92960aa5d2247dd4172a82f59738bcb5d10cafbc65efe8e8dcf373d81da7e4544e3fc0c938937fd33e343f7e672cd7
data/README.md CHANGED
@@ -3,12 +3,32 @@
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 traverse trees using single SQL query.
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 in hierarchical order using hierarchical query builder.
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
- # returned value is just regular ActiveRecord::Relation instance, so you can use its methods
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 attributes `id`, `parent_id`
113
- and `name`. You can traverse nodes recursively starting from root rows connected by
114
- `parent_id` column ordered by `name`:
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
- * **START WITH** clause
133
+ - **START WITH** clause
127
134
 
128
135
  This clause specifies the root row(s) of the hierarchy.
129
- * **CONNECT BY** clause
136
+
137
+ - **CONNECT BY** clause
130
138
 
131
139
  This clause specifies relationship between parent rows and child rows of the hierarchy.
132
- * **ORDER SIBLINGS** clause
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
- * First, root rows are selected -- those rows that satisfy `START WITH` condition in
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
- * Second, child rows for each root rows are selected. Each child row must satisfy
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
- * Successive generations of child rows are selected with respect to `CONNECT BY` clause.
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 columns in `SELECT` clause!
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 graph is not acyclic).
226
- `NOCYCLE` clause, which is turned off by default, could prevent it.
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 query will never end:
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
- By default, the union term in the Common Table Expression uses a `UNION ALL`. If you want
259
- to `SELECT DISTINCT` CTE values, add a query option for `distinct`:
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 to `join_recursive`:
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
- would generate following SQL (if PostgreSQL used):
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`, add a query option for `outer_join_hierarchical`. This option allows the query to return non-hierarchical entries:
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 to change the foreign_key on the recursive view from the primary key of the main table to another column:
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
- * [About hierarchical queries (Wikipedia)](http://en.wikipedia.org/wiki/Hierarchical_and_recursive_queries_in_SQL)
340
- * [Hierarchical queries in Oracle](http://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm)
341
- * [Recursive queries in PostgreSQL](http://www.postgresql.org/docs/9.3/static/queries-with.html)
342
- * [Using Recursive SQL with ActiveRecord trees](http://hashrocket.com/blog/posts/recursive-sql-in-activerecord)
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
- 1. Fork it ( http://github.com/take-five/activerecord-hierarchical_query/fork )
347
- 2. Create your feature branch (`git checkout -b my-new-feature`)
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
- @query.join_conditions.grep(Arel::Attributes::Attribute) { |column| column.name.to_s }
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
- def bind_values
18
- scope.bound_attributes
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
- def bind_values
16
- scope.bound_attributes
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
- def bind_values
15
- non_recursive_term.bind_values + recursive_term.bind_values
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
- # copy bound variables from inner subquery
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
- @table_name = alias_node.name
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
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module HierarchicalQuery
3
- VERSION = '1.0.1'
3
+ VERSION = '1.3.0'
4
4
  end
5
5
  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
- load SPEC_ROOT.join('schema.rb')
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|
@@ -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.1
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: 2017-06-21 00:00:00.000000000 Z
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: 3.1.0
20
+ version: '5.0'
20
21
  - - "<"
21
22
  - !ruby/object:Gem::Version
22
- version: '5.2'
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: 3.1.0
30
+ version: '5.0'
30
31
  - - "<"
31
32
  - !ruby/object:Gem::Version
32
- version: '5.2'
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.5'
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.5'
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: 10.4.2
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: 10.4.2
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.1.0
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.1.0
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.3.0
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.3.0
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.14.1
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.14.1
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
- rubyforge_project:
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