edge 0.4.3 → 0.6.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 +5 -5
- data/.travis.yml +4 -6
- data/CHANGELOG.md +23 -0
- data/edge.gemspec +2 -4
- data/gemfiles/{4.0.gemfile → 5.0.gemfile} +1 -1
- data/lib/edge/forest.rb +38 -31
- data/lib/edge/version.rb +1 -1
- data/spec/forest_spec.rb +24 -1
- data/spec/spec_helper.rb +8 -26
- metadata +11 -42
- data/gemfiles/4.1.gemfile +0 -5
- data/gemfiles/4.2.gemfile +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9ee55cbc8cd29fcd367b1423df3ecef782eb3ab3f6cc054f86373e35518fbbea
|
4
|
+
data.tar.gz: a8565592a8020190a13a04291252508b459c63deb270f220a91f54333a244779
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb8afdfdadae80f8e073a3ce094d2361dc5f47de9ed540b3ff309d40a8b9a9c12cc60c6beb2946a752a7938c7246e4841b66374d111b910ffa8f2e523c7b4cde
|
7
|
+
data.tar.gz: c540a358d7cb3c4424472a4b1c80354855673d262622cc3813c3cde9fab12c1c685638fa2083cfefed51658f2ec7917de0e993b0587a7797f57bb8f6fa397333
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
# 0.6.1 (February 20, 2021)
|
2
|
+
|
3
|
+
* Add Ruby 3 compatibility (Martins Polakovs)
|
4
|
+
|
5
|
+
# 0.6.0 (December 13, 2018)
|
6
|
+
|
7
|
+
* Fix usage when table name includes schema
|
8
|
+
* Drop Rails 4.x support
|
9
|
+
|
10
|
+
# 0.5.1 (August 4, 2017)
|
11
|
+
|
12
|
+
* Allow use of 'optional' option for belongs_to (Yuji Yaginuma)
|
13
|
+
|
14
|
+
# 0.5.0 (May 14, 2016)
|
15
|
+
|
16
|
+
* Add Rails 5.0 support
|
17
|
+
* Drop Rails 4.0 support
|
18
|
+
* Replace using internal arel with SQL string building
|
19
|
+
|
20
|
+
# 0.4.4 (January 29, 2016)
|
21
|
+
|
22
|
+
* Fix JRuby compatibility (jackc)
|
23
|
+
|
1
24
|
# 0.4.3 (October 23, 2015)
|
2
25
|
|
3
26
|
* Allow dependent option to acts_as_forest (WANG QUANG)
|
data/edge.gemspec
CHANGED
@@ -15,12 +15,10 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = Edge::VERSION
|
17
17
|
|
18
|
-
gem.add_dependency 'activerecord', ">=
|
18
|
+
gem.add_dependency 'activerecord', ">= 5.0.0"
|
19
19
|
|
20
20
|
gem.add_development_dependency 'pg'
|
21
21
|
gem.add_development_dependency 'pry'
|
22
22
|
gem.add_development_dependency 'rake'
|
23
|
-
gem.add_development_dependency 'rspec', "~> 3.
|
24
|
-
gem.add_development_dependency 'guard', ">= 0.10.0"
|
25
|
-
gem.add_development_dependency 'guard-rspec', ">= 0.6.0"
|
23
|
+
gem.add_development_dependency 'rspec', "~> 3.6.0"
|
26
24
|
end
|
data/lib/edge/forest.rb
CHANGED
@@ -7,8 +7,9 @@ module Edge
|
|
7
7
|
# * dependent - passed to children has_many (default: none)
|
8
8
|
# * foreign_key - column name to use for parent foreign_key (default: parent_id)
|
9
9
|
# * order - how to order children (default: none)
|
10
|
+
# * optional - passed to belongs_to (default: none)
|
10
11
|
def acts_as_forest(options={})
|
11
|
-
options.assert_valid_keys :foreign_key, :order, :dependent
|
12
|
+
options.assert_valid_keys :foreign_key, :order, :dependent, :optional
|
12
13
|
|
13
14
|
class_attribute :forest_foreign_key
|
14
15
|
self.forest_foreign_key = options[:foreign_key] || "parent_id"
|
@@ -23,12 +24,14 @@ module Edge
|
|
23
24
|
|
24
25
|
dependent_options = options[:dependent] ? { dependent: options[:dependent] } : {}
|
25
26
|
|
26
|
-
|
27
|
+
optional_options = options[:optional] ? { optional: options[:optional] } : {}
|
28
|
+
|
29
|
+
belongs_to :parent, **common_options.merge(inverse_of: :children).merge(optional_options)
|
27
30
|
|
28
31
|
if forest_order
|
29
|
-
has_many :children, -> { order(forest_order) }, common_options.merge(inverse_of: :parent).merge(dependent_options)
|
32
|
+
has_many :children, -> { order(forest_order) }, **common_options.merge(inverse_of: :parent).merge(dependent_options)
|
30
33
|
else
|
31
|
-
has_many :children, common_options.merge(inverse_of: :parent).merge(dependent_options)
|
34
|
+
has_many :children, **common_options.merge(inverse_of: :parent).merge(dependent_options)
|
32
35
|
end
|
33
36
|
|
34
37
|
scope :root, -> { where(forest_foreign_key => nil) }
|
@@ -49,11 +52,14 @@ module Edge
|
|
49
52
|
# # loads all nodes with matching names and all there descendants
|
50
53
|
# Category.where(:name => %w{clothing books electronics}).find_forest
|
51
54
|
def find_forest
|
52
|
-
|
53
|
-
|
55
|
+
new_scope = unscoped.joins("INNER JOIN all_nodes USING(#{connection.quote_column_name primary_key})")
|
56
|
+
new_scope = new_scope.order(forest_order) if forest_order
|
54
57
|
|
55
|
-
|
56
|
-
|
58
|
+
sql = <<-SQL
|
59
|
+
#{cte_sql}
|
60
|
+
#{new_scope.to_sql}
|
61
|
+
SQL
|
62
|
+
records = find_by_sql sql
|
57
63
|
|
58
64
|
records_by_id = records.each_with_object({}) { |r, h| h[r.id] = r }
|
59
65
|
|
@@ -97,32 +103,33 @@ module Edge
|
|
97
103
|
#
|
98
104
|
# Only where scopes can precede this in a scope chain
|
99
105
|
def with_descendants
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
106
|
+
subquery_scope = unscoped
|
107
|
+
.joins("INNER JOIN all_nodes USING(#{connection.quote_column_name primary_key})")
|
108
|
+
.select(primary_key)
|
109
|
+
|
110
|
+
subquery_sql = <<-SQL
|
111
|
+
#{cte_sql}
|
112
|
+
#{subquery_scope.to_sql}
|
113
|
+
SQL
|
114
|
+
|
115
|
+
unscoped.where <<-SQL
|
116
|
+
#{connection.quote_column_name primary_key} IN (#{subquery_sql})
|
117
|
+
SQL
|
104
118
|
end
|
105
119
|
|
106
120
|
private
|
107
|
-
def
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
as_statement = Arel::Nodes::As.new all_nodes, union
|
120
|
-
|
121
|
-
Arel::SelectManager.new(Arel::Table.engine)
|
122
|
-
.with(:recursive, as_statement)
|
123
|
-
.from(all_nodes)
|
124
|
-
.join(arel_table)
|
125
|
-
.on(all_nodes[:id].eq(arel_table[:id]))
|
121
|
+
def cte_sql
|
122
|
+
quoted_table_name = '"locations"'
|
123
|
+
original_scope = (current_scope || all).select(primary_key, forest_foreign_key)
|
124
|
+
iterated_scope = unscoped.select(primary_key, forest_foreign_key)
|
125
|
+
.joins("INNER JOIN all_nodes ON #{connection.quote_table_name table_name}.#{connection.quote_column_name forest_foreign_key}=all_nodes.#{connection.quote_column_name primary_key}")
|
126
|
+
<<-SQL
|
127
|
+
WITH RECURSIVE all_nodes AS (
|
128
|
+
#{original_scope.to_sql}
|
129
|
+
UNION
|
130
|
+
#{iterated_scope.to_sql}
|
131
|
+
)
|
132
|
+
SQL
|
126
133
|
end
|
127
134
|
end
|
128
135
|
|
data/lib/edge/version.rb
CHANGED
data/spec/forest_spec.rb
CHANGED
@@ -164,7 +164,8 @@ describe "Edge::Forest" do
|
|
164
164
|
|
165
165
|
it "works when scoped" do
|
166
166
|
forest = Location.where(:name => "USA").find_forest
|
167
|
-
expect(forest).to
|
167
|
+
expect(forest).to match_array([usa])
|
168
|
+
expect(forest.first.children).to match_array([illinois, indiana])
|
168
169
|
end
|
169
170
|
|
170
171
|
it "preloads children in proper order" do
|
@@ -257,4 +258,26 @@ describe "Edge::Forest" do
|
|
257
258
|
end
|
258
259
|
|
259
260
|
end
|
261
|
+
|
262
|
+
if ActiveRecord::VERSION::MAJOR >= 5
|
263
|
+
describe "optional option" do
|
264
|
+
before do
|
265
|
+
@original_value = ActiveRecord::Base.belongs_to_required_by_default
|
266
|
+
ActiveRecord::Base.belongs_to_required_by_default = true
|
267
|
+
end
|
268
|
+
|
269
|
+
after do
|
270
|
+
ActiveRecord::Base.belongs_to_required_by_default = @original_value
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'parent can be nil' do
|
274
|
+
class Location4 < ActiveRecord::Base
|
275
|
+
self.table_name = "locations"
|
276
|
+
acts_as_forest optional: true
|
277
|
+
end
|
278
|
+
|
279
|
+
expect(Location4.new(name: "Iceland").valid?).to eq true
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
260
283
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -6,36 +6,18 @@ require 'rspec'
|
|
6
6
|
database_config = YAML.load_file(File.expand_path("../database.yml", __FILE__))
|
7
7
|
ActiveRecord::Base.establish_connection database_config["test"]
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
# class HstoreRecord < ActiveRecord::Base
|
12
|
-
# serialize :properties, Surus::Hstore::Serializer.new
|
13
|
-
# end
|
14
|
-
|
15
|
-
# class TextArrayRecord < ActiveRecord::Base
|
16
|
-
# serialize :texts, Surus::Array::TextSerializer.new
|
17
|
-
# end
|
18
|
-
|
19
|
-
# class IntegerArrayRecord < ActiveRecord::Base
|
20
|
-
# serialize :integers, Surus::Array::IntegerSerializer.new
|
21
|
-
# end
|
22
|
-
|
23
|
-
# class FloatArrayRecord < ActiveRecord::Base
|
24
|
-
# serialize :floats, Surus::Array::FloatSerializer.new
|
25
|
-
# end
|
26
|
-
|
27
|
-
# class DecimalArrayRecord < ActiveRecord::Base
|
28
|
-
# serialize :decimals, Surus::Array::DecimalSerializer.new
|
29
|
-
# end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
9
|
RSpec.configure do |config|
|
34
|
-
config.
|
10
|
+
config.before(:all) do |example|
|
11
|
+
ActiveRecord::Base.connection.execute <<-SQL
|
12
|
+
truncate body_parts;
|
13
|
+
truncate locations;
|
14
|
+
SQL
|
15
|
+
end
|
16
|
+
|
17
|
+
config.around do |example|
|
35
18
|
ActiveRecord::Base.transaction do
|
36
19
|
example.call
|
37
20
|
raise ActiveRecord::Rollback
|
38
21
|
end
|
39
22
|
end
|
40
23
|
end
|
41
|
-
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: edge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jack Christensen
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 5.0.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:
|
26
|
+
version: 5.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: pg
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,42 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 3.
|
75
|
+
version: 3.6.0
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 3.
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: guard
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: 0.10.0
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: 0.10.0
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: guard-rspec
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: 0.6.0
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - ">="
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: 0.6.0
|
82
|
+
version: 3.6.0
|
111
83
|
description: Graph functionality for ActiveRecord
|
112
84
|
email:
|
113
85
|
- jack@jackchristensen.com
|
@@ -129,9 +101,7 @@ files:
|
|
129
101
|
- bench/database_structure.sql
|
130
102
|
- bench/forest_find.rb
|
131
103
|
- edge.gemspec
|
132
|
-
- gemfiles/
|
133
|
-
- gemfiles/4.1.gemfile
|
134
|
-
- gemfiles/4.2.gemfile
|
104
|
+
- gemfiles/5.0.gemfile
|
135
105
|
- lib/edge.rb
|
136
106
|
- lib/edge/forest.rb
|
137
107
|
- lib/edge/version.rb
|
@@ -143,7 +113,7 @@ files:
|
|
143
113
|
homepage: https://github.com/JackC/edge
|
144
114
|
licenses: []
|
145
115
|
metadata: {}
|
146
|
-
post_install_message:
|
116
|
+
post_install_message:
|
147
117
|
rdoc_options: []
|
148
118
|
require_paths:
|
149
119
|
- lib
|
@@ -158,9 +128,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
158
128
|
- !ruby/object:Gem::Version
|
159
129
|
version: '0'
|
160
130
|
requirements: []
|
161
|
-
|
162
|
-
|
163
|
-
signing_key:
|
131
|
+
rubygems_version: 3.0.6
|
132
|
+
signing_key:
|
164
133
|
specification_version: 4
|
165
134
|
summary: Graph functionality for ActiveRecord. Provides tree/forest modeling structure
|
166
135
|
that can load entire trees in a single query.
|
data/gemfiles/4.1.gemfile
DELETED