closure_tree 6.4.0 → 7.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.travis.yml +19 -12
  4. data/Appraisals +75 -7
  5. data/CHANGELOG.md +92 -39
  6. data/Gemfile +0 -12
  7. data/README.md +67 -24
  8. data/_config.yml +1 -0
  9. data/closure_tree.gemspec +10 -7
  10. data/lib/closure_tree/finders.rb +32 -9
  11. data/lib/closure_tree/has_closure_tree.rb +4 -0
  12. data/lib/closure_tree/has_closure_tree_root.rb +4 -6
  13. data/lib/closure_tree/hash_tree_support.rb +4 -4
  14. data/lib/closure_tree/hierarchy_maintenance.rb +31 -11
  15. data/lib/closure_tree/model.rb +42 -16
  16. data/lib/closure_tree/numeric_deterministic_ordering.rb +20 -6
  17. data/lib/closure_tree/numeric_order_support.rb +7 -3
  18. data/lib/closure_tree/support.rb +18 -12
  19. data/lib/closure_tree/support_attributes.rb +10 -1
  20. data/lib/closure_tree/support_flags.rb +1 -4
  21. data/lib/closure_tree/version.rb +1 -1
  22. data/lib/generators/closure_tree/migration_generator.rb +8 -0
  23. data/lib/generators/closure_tree/templates/create_hierarchies_table.rb.erb +1 -1
  24. metadata +29 -75
  25. data/gemfiles/activerecord_4.2.gemfile +0 -19
  26. data/gemfiles/activerecord_5.0.gemfile +0 -19
  27. data/gemfiles/activerecord_5.0_foreigner.gemfile +0 -20
  28. data/gemfiles/activerecord_edge.gemfile +0 -20
  29. data/img/example.png +0 -0
  30. data/img/preorder.png +0 -0
  31. data/spec/cache_invalidation_spec.rb +0 -39
  32. data/spec/cuisine_type_spec.rb +0 -38
  33. data/spec/db/database.yml +0 -21
  34. data/spec/db/models.rb +0 -128
  35. data/spec/db/schema.rb +0 -166
  36. data/spec/fixtures/tags.yml +0 -98
  37. data/spec/generators/migration_generator_spec.rb +0 -48
  38. data/spec/has_closure_tree_root_spec.rb +0 -154
  39. data/spec/hierarchy_maintenance_spec.rb +0 -16
  40. data/spec/label_spec.rb +0 -554
  41. data/spec/matcher_spec.rb +0 -34
  42. data/spec/metal_spec.rb +0 -55
  43. data/spec/model_spec.rb +0 -9
  44. data/spec/namespace_type_spec.rb +0 -13
  45. data/spec/parallel_spec.rb +0 -159
  46. data/spec/spec_helper.rb +0 -24
  47. data/spec/support/database.rb +0 -52
  48. data/spec/support/database_cleaner.rb +0 -14
  49. data/spec/support/exceed_query_limit.rb +0 -18
  50. data/spec/support/hash_monkey_patch.rb +0 -13
  51. data/spec/support/query_counter.rb +0 -18
  52. data/spec/support/sqlite3_with_advisory_lock.rb +0 -10
  53. data/spec/support_spec.rb +0 -14
  54. data/spec/tag_examples.rb +0 -665
  55. data/spec/tag_spec.rb +0 -6
  56. data/spec/user_spec.rb +0 -174
  57. data/spec/uuid_tag_spec.rb +0 -6
@@ -1,19 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "~> 4.2.0"
6
-
7
- platforms :ruby, :rbx do
8
- gem "mysql2"
9
- gem "pg"
10
- gem "sqlite3"
11
- end
12
-
13
- platforms :jruby do
14
- gem "activerecord-jdbcmysql-adapter"
15
- gem "activerecord-jdbcpostgresql-adapter"
16
- gem "activerecord-jdbcsqlite3-adapter"
17
- end
18
-
19
- gemspec :path => "../"
@@ -1,19 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "~> 5.0.0"
6
-
7
- platforms :ruby, :rbx do
8
- gem "mysql2"
9
- gem "pg"
10
- gem "sqlite3"
11
- end
12
-
13
- platforms :jruby do
14
- gem "activerecord-jdbcmysql-adapter"
15
- gem "activerecord-jdbcpostgresql-adapter"
16
- gem "activerecord-jdbcsqlite3-adapter"
17
- end
18
-
19
- gemspec :path => "../"
@@ -1,20 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "~> 5.0.0"
6
- gem "foreigner"
7
-
8
- platforms :ruby, :rbx do
9
- gem "mysql2"
10
- gem "pg"
11
- gem "sqlite3"
12
- end
13
-
14
- platforms :jruby do
15
- gem "activerecord-jdbcmysql-adapter"
16
- gem "activerecord-jdbcpostgresql-adapter"
17
- gem "activerecord-jdbcsqlite3-adapter"
18
- end
19
-
20
- gemspec :path => "../"
@@ -1,20 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", :github => "rails/rails"
6
- gem "arel", :github => "rails/arel"
7
-
8
- platforms :ruby, :rbx do
9
- gem "mysql2"
10
- gem "pg"
11
- gem "sqlite3"
12
- end
13
-
14
- platforms :jruby do
15
- gem "activerecord-jdbcmysql-adapter"
16
- gem "activerecord-jdbcpostgresql-adapter"
17
- gem "activerecord-jdbcsqlite3-adapter"
18
- end
19
-
20
- gemspec :path => "../"
Binary file
Binary file
@@ -1,39 +0,0 @@
1
- require 'spec_helper'
2
-
3
-
4
- describe 'cache invalidation', cache: true do
5
- before do
6
- Timecop.travel(10.seconds.ago) do
7
- #create a long tree with 2 branch
8
- @root = MenuItem.create(
9
- name: SecureRandom.hex(10)
10
- )
11
- 2.times do
12
- parent = @root
13
- 10.times do
14
- parent = parent.children.create(
15
- name: SecureRandom.hex(10)
16
- )
17
- end
18
- end
19
- @first_leaf = MenuItem.leaves.first
20
- @second_leaf = MenuItem.leaves.last
21
- end
22
- end
23
-
24
- describe 'touch option' do
25
- it 'should invalidate cache for all it ancestors' do
26
- old_time_stamp = @first_leaf.ancestors.pluck(:updated_at)
27
- @first_leaf.touch
28
- new_time_stamp = @first_leaf.ancestors.pluck(:updated_at)
29
- expect(old_time_stamp).to_not eq(new_time_stamp)
30
- end
31
-
32
- it 'should not invalidate cache for another branch' do
33
- old_time_stamp = @second_leaf.updated_at
34
- @first_leaf.touch
35
- new_time_stamp = @second_leaf.updated_at
36
- expect(old_time_stamp).to eq(new_time_stamp)
37
- end
38
- end
39
- end
@@ -1,38 +0,0 @@
1
- require 'spec_helper'
2
-
3
- def assert_lineage(e, m)
4
- expect(m.parent).to eq(e)
5
- expect(m.self_and_ancestors).to eq([m, e])
6
-
7
- # make sure reloading doesn't affect the self_and_ancestors:
8
- m.reload
9
- expect(m.self_and_ancestors).to eq([m, e])
10
- end
11
-
12
- describe CuisineType do
13
- it "finds self and parents when children << is used" do
14
- e = CuisineType.new(:name => "e")
15
- m = CuisineType.new(:name => "m")
16
- e.children << m
17
- e.save
18
- assert_lineage(e, m)
19
- end
20
-
21
- it "finds self and parents properly if the constructor is used" do
22
- e = CuisineType.create(:name => "e")
23
- m = CuisineType.create(:name => "m", :parent => e)
24
- assert_lineage(e, m)
25
- end
26
-
27
- it "sets the table_name of the hierarchy class properly" do
28
- expect(CuisineTypeHierarchy.table_name).to eq(ActiveRecord::Base.table_name_prefix + "cuisine_type_hierarchies" + ActiveRecord::Base.table_name_suffix)
29
- end
30
-
31
- it 'fixes self_and_ancestors properly on reparenting' do
32
- a = CuisineType.create! :name => 'a'
33
- b = CuisineType.create! :name => 'b'
34
- expect(b.self_and_ancestors.to_a).to eq([b])
35
- a.children << b
36
- expect(b.self_and_ancestors.to_a).to eq([b, a])
37
- end
38
- end
@@ -1,21 +0,0 @@
1
- common: &common
2
- database: <%= db_name %>
3
- host: localhost
4
- pool: 50
5
- timeout: 5000
6
- reaping_frequency: 1000
7
- min_messages: ERROR
8
-
9
- sqlite:
10
- <<: *common
11
- adapter: <%= "jdbc" if defined? JRUBY_VERSION %>sqlite3
12
-
13
- postgresql:
14
- <<: *common
15
- adapter: postgresql
16
- username: postgres
17
-
18
- mysql:
19
- <<: *common
20
- adapter: mysql2
21
- username: root
@@ -1,128 +0,0 @@
1
- class Tag < ActiveRecord::Base
2
- has_closure_tree :dependent => :destroy, :order => :name
3
- before_destroy :add_destroyed_tag
4
-
5
- def to_s
6
- name
7
- end
8
-
9
- def add_destroyed_tag
10
- # Proof for the tests that the destroy rather than the delete method was called:
11
- DestroyedTag.create(:name => name)
12
- end
13
- end
14
-
15
- class UUIDTag < ActiveRecord::Base
16
- self.primary_key = :uuid
17
- before_create :set_uuid
18
- has_closure_tree dependent: :destroy, order: 'name', parent_column_name: 'parent_uuid'
19
- before_destroy :add_destroyed_tag
20
-
21
- def set_uuid
22
- self.uuid = SecureRandom.uuid
23
- end
24
-
25
- def to_s
26
- name
27
- end
28
-
29
- def add_destroyed_tag
30
- # Proof for the tests that the destroy rather than the delete method was called:
31
- DestroyedTag.create(:name => name)
32
- end
33
- end
34
-
35
- class DestroyedTag < ActiveRecord::Base
36
- end
37
-
38
- class Group < ActiveRecord::Base
39
- has_closure_tree_root :root_user
40
- end
41
-
42
- class Grouping < ActiveRecord::Base
43
- has_closure_tree_root :root_person, class_name: "User", foreign_key: :group_id
44
- end
45
-
46
- class UserSet < ActiveRecord::Base
47
- has_closure_tree_root :root_user, class_name: "Useur"
48
- end
49
-
50
- class Team < ActiveRecord::Base
51
- has_closure_tree_root :root_user, class_name: "User", foreign_key: :grp_id
52
- end
53
-
54
- class User < ActiveRecord::Base
55
- acts_as_tree :parent_column_name => "referrer_id",
56
- :name_column => 'email',
57
- :hierarchy_class_name => 'ReferralHierarchy',
58
- :hierarchy_table_name => 'referral_hierarchies'
59
-
60
- has_many :contracts, inverse_of: :user
61
- belongs_to :group # Can't use and don't need inverse_of here when using has_closure_tree_root.
62
-
63
- def indirect_contracts
64
- Contract.where(:user_id => descendant_ids)
65
- end
66
-
67
- def to_s
68
- email
69
- end
70
- end
71
-
72
- class Contract < ActiveRecord::Base
73
- belongs_to :user, inverse_of: :contracts
74
- belongs_to :contract_type, inverse_of: :contracts
75
- end
76
-
77
- class ContractType < ActiveRecord::Base
78
- has_many :contracts, inverse_of: :contract_type
79
- end
80
-
81
- class Label < ActiveRecord::Base
82
- # make sure order doesn't matter
83
- acts_as_tree :order => :column_whereby_ordering_is_inferred, # <- symbol, and not "sort_order"
84
- :parent_column_name => "mother_id",
85
- :dependent => :destroy
86
-
87
- def to_s
88
- "#{self.class}: #{name}"
89
- end
90
- end
91
-
92
- class EventLabel < Label
93
- end
94
-
95
- class DateLabel < Label
96
- end
97
-
98
- class DirectoryLabel < Label
99
- end
100
-
101
- class CuisineType < ActiveRecord::Base
102
- acts_as_tree
103
- end
104
-
105
- module Namespace
106
- def self.table_name_prefix
107
- 'namespace_'
108
- end
109
- class Type < ActiveRecord::Base
110
- has_closure_tree dependent: :destroy
111
- end
112
- end
113
-
114
- class Metal < ActiveRecord::Base
115
- self.table_name = "#{table_name_prefix}metal#{table_name_suffix}"
116
- has_closure_tree order: 'sort_order', name_column: 'value'
117
- self.inheritance_column = 'metal_type'
118
- end
119
-
120
- class Adamantium < Metal
121
- end
122
-
123
- class Unobtanium < Metal
124
- end
125
-
126
- class MenuItem < ActiveRecord::Base
127
- has_closure_tree touch: true, with_advisory_lock: false
128
- end
@@ -1,166 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- ActiveRecord::Schema.define(:version => 0) do
4
-
5
- create_table "tags" do |t|
6
- t.string "name"
7
- t.string "title"
8
- t.integer "parent_id"
9
- t.integer "sort_order"
10
- t.timestamps null: false
11
- end
12
-
13
- add_foreign_key(:tags, :tags, :column => 'parent_id')
14
-
15
- create_table "tag_hierarchies", :id => false do |t|
16
- t.integer "ancestor_id", :null => false
17
- t.integer "descendant_id", :null => false
18
- t.integer "generations", :null => false
19
- end
20
-
21
- add_foreign_key(:tag_hierarchies, :tags, :column => 'ancestor_id')
22
- add_foreign_key(:tag_hierarchies, :tags, :column => 'descendant_id')
23
-
24
- create_table "uuid_tags", :id => false do |t|
25
- t.string "uuid", :unique => true
26
- t.string "name"
27
- t.string "title"
28
- t.string "parent_uuid"
29
- t.integer "sort_order"
30
- t.timestamps null: false
31
- end
32
-
33
- create_table "uuid_tag_hierarchies", :id => false do |t|
34
- t.string "ancestor_id", :null => false
35
- t.string "descendant_id", :null => false
36
- t.integer "generations", :null => false
37
- end
38
-
39
- create_table "destroyed_tags" do |t|
40
- t.string "name"
41
- end
42
-
43
- add_index "tag_hierarchies", [:ancestor_id, :descendant_id, :generations], :unique => true, :name => "tag_anc_desc_idx"
44
- add_index "tag_hierarchies", [:descendant_id], :name => "tag_desc_idx"
45
-
46
- create_table "groups" do |t|
47
- t.string "name", null: false
48
- end
49
-
50
- create_table "groupings" do |t|
51
- t.string "name", null: false
52
- end
53
-
54
- create_table "user_sets" do |t|
55
- t.string "name", null: false
56
- end
57
-
58
- create_table "teams" do |t|
59
- t.string "name", null: false
60
- end
61
-
62
- create_table "users" do |t|
63
- t.string "email"
64
- t.integer "referrer_id"
65
- t.integer "group_id"
66
- t.timestamps null: false
67
- end
68
-
69
- add_foreign_key(:users, :users, :column => 'referrer_id')
70
-
71
- create_table "contracts" do |t|
72
- t.integer "user_id", :null => false
73
- t.integer "contract_type_id"
74
- t.string "title"
75
- end
76
-
77
- create_table "contract_types" do |t|
78
- t.string "name", :null => false
79
- end
80
-
81
- create_table "referral_hierarchies", :id => false do |t|
82
- t.integer "ancestor_id", :null => false
83
- t.integer "descendant_id", :null => false
84
- t.integer "generations", :null => false
85
- end
86
-
87
- add_index "referral_hierarchies", [:ancestor_id, :descendant_id, :generations], :unique => true, :name => "ref_anc_desc_idx"
88
- add_index "referral_hierarchies", [:descendant_id], :name => "ref_desc_idx"
89
-
90
- create_table "labels" do |t|
91
- t.string "name"
92
- t.string "type"
93
- t.integer "column_whereby_ordering_is_inferred"
94
- t.integer "mother_id"
95
- end
96
-
97
- add_foreign_key(:labels, :labels, :column => 'mother_id')
98
-
99
- create_table "label_hierarchies", :id => false do |t|
100
- t.integer "ancestor_id", :null => false
101
- t.integer "descendant_id", :null => false
102
- t.integer "generations", :null => false
103
- end
104
-
105
- add_index "label_hierarchies", [:ancestor_id, :descendant_id, :generations], :unique => true, :name => "lh_anc_desc_idx"
106
- add_index "label_hierarchies", [:descendant_id], :name => "lh_desc_idx"
107
-
108
- create_table "cuisine_types" do |t|
109
- t.string "name"
110
- t.integer "parent_id"
111
- end
112
-
113
- create_table "cuisine_type_hierarchies", :id => false do |t|
114
- t.integer "ancestor_id", :null => false
115
- t.integer "descendant_id", :null => false
116
- t.integer "generations", :null => false
117
- end
118
-
119
- create_table "namespace_types" do |t|
120
- t.string "name"
121
- t.integer "parent_id"
122
- end
123
-
124
- create_table "namespace_type_hierarchies", :id => false do |t|
125
- t.integer "ancestor_id", :null => false
126
- t.integer "descendant_id", :null => false
127
- t.integer "generations", :null => false
128
- end
129
-
130
- create_table "metal" do |t|
131
- t.integer "parent_id"
132
- t.string "metal_type"
133
- t.string "value"
134
- t.string "description"
135
- t.integer "sort_order"
136
- end
137
-
138
- add_foreign_key(:metal, :metal, :column => 'parent_id')
139
-
140
- create_table "metal_hierarchies", :id => false do |t|
141
- t.integer "ancestor_id", :null => false
142
- t.integer "descendant_id", :null => false
143
- t.integer "generations", :null => false
144
- end
145
-
146
- add_foreign_key(:metal_hierarchies, :metal, :column => 'ancestor_id')
147
- add_foreign_key(:metal_hierarchies, :metal, :column => 'descendant_id')
148
-
149
- create_table 'menu_items' do |t|
150
- t.string 'name'
151
- t.integer 'parent_id'
152
- t.timestamps null: false
153
- end
154
-
155
- add_foreign_key(:menu_items, :menu_items, :column => 'parent_id')
156
-
157
- create_table 'menu_item_hierarchies', :id => false do |t|
158
- t.integer 'ancestor_id', :null => false
159
- t.integer 'descendant_id', :null => false
160
- t.integer 'generations', :null => false
161
- end
162
-
163
- add_foreign_key(:menu_item_hierarchies, :menu_items, :column => 'ancestor_id')
164
- add_foreign_key(:menu_item_hierarchies, :menu_items, :column => 'descendant_id')
165
-
166
- end