with_recursive_tree 0.1.1 → 0.2.1

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
2
  SHA256:
3
- metadata.gz: e14936619fe555cbfb5024c1284f48645ce74ce15ea4f8d0986ba29181b4bd9d
4
- data.tar.gz: a1edfad9f5e95ba7aa8a812703b8c73288840bf6aeb56a2334a47b7bbdd58d76
3
+ metadata.gz: 92e7fa34c82ec4cde4ba95072d52009f5c34925df14fdadbeb1e82dbfae61524
4
+ data.tar.gz: 3b463ddbb8dc0170a72fc1b80d77a435b38baa3b6007e69e1ef43f688adde112
5
5
  SHA512:
6
- metadata.gz: 3eab819caf4873be68501e1f0c4458d1e7c3dfdadc76331935be5ef93840ba57938dbbbdae48666e2e7bb63c5e7cca6106cf6b757fc51ae3214acc761138d974
7
- data.tar.gz: deb8c83129e99787021939d4176bbef60b45e1edcf1f572d3076abe24e361205284e346f0320f68437e8eac0f13484b55d9975b6047af1bae5a21768ee3cd238
6
+ metadata.gz: b4459dccf11b54213f50269c227e9c05af2efff4347905c5504db438fa9b0970ed47c66cbf0b9938a74f4fc95acfc3f5d20bfa9f6654547b4fcbc89df538b811
7
+ data.tar.gz: 873f7e500d51a922defb6bd8eaade92a864d99de5d80d835a2ef2cd4c6f1107928526b0eb5777919a560dbbb50df6f534b0619f4c65eee1c3d648b1f4f318cc3
data/README.md CHANGED
@@ -144,6 +144,16 @@ A
144
144
  ---R
145
145
  ```
146
146
 
147
+ ## Compatibility
148
+
149
+ with_recursive_tree is compatible with:
150
+
151
+ * Rails 6.0 and above
152
+ * Ruby 3.1 and above
153
+ * Postgres version 13 and above
154
+ * MySQL version 8 and above
155
+ * SQLite3 version 3.34 and above
156
+
147
157
  ## Benchmarks
148
158
 
149
159
  You can run some [benchmarks](/benchmarks/benchmark.rb) to compare with_recursive_tree agains [acts_as_tree](https://github.com/amerine/acts_as_tree), [ancestry](https://github.com/stefankroes/ancestry/) and [closure_tree](https://github.com/ClosureTree/closure_tree).
@@ -0,0 +1,60 @@
1
+ module WithRecursiveTree
2
+ def ancestors
3
+ self_and_ancestors.where.not self.class.with_recursive_tree_primary_key => send(self.class.with_recursive_tree_primary_key)
4
+ end
5
+
6
+ def descendants
7
+ self_and_descendants.where.not self.class.with_recursive_tree_primary_key => send(self.class.with_recursive_tree_primary_key)
8
+ end
9
+
10
+ def self_and_ancestors
11
+ sql = <<-SQL
12
+ WITH RECURSIVE tree AS (
13
+ #{self.class.where(self.class.with_recursive_tree_primary_key => send(self.class.with_recursive_tree_primary_key)).to_sql}
14
+ UNION ALL
15
+ #{self.class.joins("JOIN tree ON #{self.class.table_name}.#{self.class.with_recursive_tree_primary_key} = tree.#{self.class.with_recursive_tree_foreign_key}").to_sql}
16
+ ) SELECT * FROM tree
17
+ SQL
18
+
19
+ self.class.select("*").from("(#{sql}) AS #{self.class.table_name}")
20
+ end
21
+
22
+ def self_and_descendants
23
+ anchor_path = if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
24
+ "ARRAY[#{self.class.with_recursive_tree_order_column}]::text[]"
25
+ elsif defined?(ActiveRecord::ConnectionAdapters::MySQL)
26
+ "CAST(CONCAT('/', #{self.class.with_recursive_tree_primary_key}, '/') AS CHAR(512))"
27
+ elsif defined?(ActiveRecord::ConnectionAdapters::SQLite3Adapter)
28
+ "'/' || #{self.class.with_recursive_tree_primary_key} || '/'"
29
+ end
30
+
31
+ recursive_path = if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
32
+ "tree.path || #{self.class.table_name}.#{self.class.with_recursive_tree_order_column}::text"
33
+ elsif defined?(ActiveRecord::ConnectionAdapters::MySQL)
34
+ "CONCAT(tree.path, #{self.class.table_name}.#{self.class.with_recursive_tree_primary_key}, '/')"
35
+ elsif defined?(ActiveRecord::ConnectionAdapters::SQLite3)
36
+ "tree.path || #{self.class.table_name}.#{self.class.with_recursive_tree_primary_key} || '/'"
37
+ end
38
+
39
+ recursive_query = self.class.joins("JOIN tree ON #{self.class.table_name}.#{self.class.with_recursive_tree_foreign_key} = tree.#{self.class.with_recursive_tree_primary_key}").select("#{self.class.table_name}.*, #{recursive_path} AS path, depth + 1 AS depth")
40
+
41
+ # order by is only available in SQLIte for rails versions older than 7.2
42
+ if defined?(ActiveRecord::ConnectionAdapters::SQLite3)
43
+ recursive_query = recursive_query.order(self.class.with_recursive_tree_order)
44
+ end
45
+
46
+ sql = <<-SQL
47
+ WITH RECURSIVE tree AS (
48
+ #{self.class.where(self.class.with_recursive_tree_primary_key => send(self.class.with_recursive_tree_primary_key)).select("*, #{anchor_path} AS path, 0 AS depth").to_sql}
49
+ UNION ALL
50
+ #{Arel.sql(recursive_query.to_sql)}
51
+ ) SELECT * FROM tree
52
+ SQL
53
+
54
+ self.class.select("*").from("(#{sql}) AS #{self.class.table_name}")
55
+ end
56
+
57
+ def siblings
58
+ self_and_siblings.where.not self.class.with_recursive_tree_primary_key => send(self.class.with_recursive_tree_primary_key)
59
+ end
60
+ end
@@ -1,3 +1,3 @@
1
1
  module WithRecursiveTree
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -122,6 +122,10 @@ module WithRecursiveTree
122
122
  end
123
123
  end
124
124
 
125
+ if Gem::Dependency.new("", "< 7.2.0").match?("", ActiveRecord::VERSION::STRING)
126
+ require "with_recursive_tree/backport"
127
+ end
128
+
125
129
  ActiveSupport.on_load :active_record do
126
130
  include WithRecursiveTree
127
131
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: with_recursive_tree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patricio Mac Adden
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-12-10 00:00:00.000000000 Z
11
+ date: 2025-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,42 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '7.2'
19
+ version: '6.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '7.2'
26
+ version: '6.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activesupport
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '7.2'
33
+ version: '6.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '7.2'
40
+ version: '6.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: railties
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '7.2'
47
+ version: '6.0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '7.2'
54
+ version: '6.0'
55
55
  description: Tree structures for ActiveRecord
56
56
  email:
57
57
  - patriciomacadden@gmail.com
@@ -62,6 +62,7 @@ files:
62
62
  - README.md
63
63
  - Rakefile
64
64
  - lib/with_recursive_tree.rb
65
+ - lib/with_recursive_tree/backport.rb
65
66
  - lib/with_recursive_tree/version.rb
66
67
  homepage: https://github.com/sinaptia/with_recursive_tree
67
68
  licenses: []
@@ -76,7 +77,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
76
77
  requirements:
77
78
  - - ">="
78
79
  - !ruby/object:Gem::Version
79
- version: '0'
80
+ version: '3.0'
80
81
  required_rubygems_version: !ruby/object:Gem::Requirement
81
82
  requirements:
82
83
  - - ">="