chronic_tree 1.0.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.
@@ -0,0 +1,9 @@
1
+ module ChronicTree
2
+ class Railtie < Rails::Railtie
3
+ initializer "chronic_tree.inject_into_active_record_base" do
4
+ ActiveSupport.on_load :active_record do
5
+ ::ActiveRecord::Base.include(ChronicTree)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,64 @@
1
+ module ChronicTree
2
+ module Travesal
3
+ def children
4
+ init_tree_args_when_nil
5
+ children_relation(current_time_at, current_scope_name).map do |el|
6
+ el.child.as_tree(current_time_at, current_scope_name)
7
+ end
8
+ end
9
+
10
+ def parent
11
+ init_tree_args_when_nil
12
+ child_element = parent_relation(current_time_at, current_scope_name).first
13
+ child_element.parent.as_tree(current_time_at, current_scope_name) if child_element
14
+ end
15
+
16
+ def root
17
+ init_tree_args_when_nil
18
+ child_element = existed_relation(current_time_at, current_scope_name).first
19
+ child_element.root.as_tree(current_time_at, current_scope_name) if child_element
20
+ end
21
+
22
+ def descendants
23
+ init_tree_args_when_nil
24
+ descendants_relation(current_time_at, current_scope_name).inject([]) do |result, el|
25
+ result[el.distance - 1] ||= []
26
+ result[el.distance - 1] << el.child.as_tree(current_time_at, current_scope_name)
27
+ result
28
+ end
29
+ end
30
+
31
+ def flat_descendants
32
+ init_tree_args_when_nil
33
+ descendants_relation(current_time_at, current_scope_name).map do |el|
34
+ el.child.as_tree(current_time_at, current_scope_name)
35
+ end
36
+ end
37
+
38
+ def ancestors
39
+ init_tree_args_when_nil
40
+ ancestors_relation(current_time_at, current_scope_name).map do |el|
41
+ el.parent.as_tree(current_time_at, current_scope_name)
42
+ end
43
+ end
44
+
45
+ alias_method :parent?, :parent
46
+
47
+ def tree_empty?(time_at = Time.now, scope_name = 'default')
48
+ ChronicTree::ActiveRecord::Element.
49
+ where(scope_name: scope_name).
50
+ at(time_at).
51
+ empty?
52
+ end
53
+
54
+ def existed_in_tree?(time_at = Time.now, scope_name = 'default')
55
+ existed_relation(time_at, scope_name).any?
56
+ end
57
+
58
+ private
59
+
60
+ def init_tree_args_when_nil
61
+ as_tree if current_time_at.nil? || current_scope_name.nil?
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,3 @@
1
+ module ChronicTree
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,15 @@
1
+ module ChronicTree
2
+ class InstallGenerator < Rails::Generators::Base
3
+
4
+ desc "This generator creates the db schema for chronic_tree gem."
5
+
6
+ source_root File.expand_path("../templates", __FILE__)
7
+
8
+ def create_migration_file
9
+ if Dir["#{destination_root}/db/migrate/*_create_chronic_tree_elements.rb"].empty?
10
+ template "create_chronic_tree_elements.rb",
11
+ "db/migrate/#{Time.now.strftime('%Y%m%d%H%M%S')}_create_chronic_tree_elements.rb"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ class CreateChronicTreeElements < ActiveRecord::Migration
2
+ def change
3
+ create_table :chronic_tree_elements do |t|
4
+ t.string :tree_type, not_null: true
5
+ t.integer :parent_id, not_null: true
6
+ t.integer :child_id, not_null: true
7
+ t.integer :root_id, not_null: true
8
+ t.integer :distance, not_null: true
9
+ t.datetime :start_time, not_null: true
10
+ t.datetime :end_time, not_null: true
11
+ t.string :scope_name, not_null: true
12
+ t.integer :position
13
+
14
+ t.index :tree_type
15
+ t.index :parent_id
16
+ t.index :child_id
17
+ t.index :root_id
18
+ t.index [:start_time, :end_time]
19
+ t.index :scope_name
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,223 @@
1
+ require 'spec_helper'
2
+
3
+ describe ChronicTree do
4
+
5
+ context "Tree Traversal" do
6
+ before(:all) do
7
+ init_simple_tree
8
+ end
9
+
10
+ after(:all) do
11
+ destroy_simple_tree
12
+ end
13
+
14
+ it "f: access non-existed scope" do
15
+ expect { @root_org.as_tree(Time.now, 'non-existed') }.to raise_error
16
+ end
17
+
18
+ it "f: access the future" do
19
+ expect { @root_org.as_tree(1.minute.from_now) }.to raise_error
20
+ end
21
+
22
+ it "s: access children" do
23
+ expect(@root_org.children.size).to be == 2
24
+ expect(@root_org.children.first.id).to be == @lv1_child_org.id
25
+ expect(@lv1_child_org.children.size).to be == 2
26
+ expect(@lv1_child_org.children.first.id).to be == @lv2_child_org.id
27
+ expect(@lv2_child_org.children.size).to be == 1
28
+ end
29
+
30
+ it "s: access parent" do
31
+ expect(@lv1_child_org.parent.id).to be == @root_org.id
32
+ expect(@lv2_child_org.parent.id).to be == @lv1_child_org.id
33
+ expect(@root_org.parent?).to be_falsy
34
+ end
35
+
36
+ it "s: access root" do
37
+ expect(@lv1_child_org.root.id).to be == @root_org.id
38
+ expect(@lv2_child_org.root.id).to be == @root_org.id
39
+ expect(@root_org.root.id).to be == @root_org.id
40
+ end
41
+
42
+ it "s: access descendants" do
43
+ expect(@root_org.descendants.size).to be == 5
44
+ expect(@root_org.flat_descendants.size).to be == 12
45
+ expect(@root_org.flat_descendants.first.id).to be == @lv1_child_org.id
46
+ expect(@root_org.flat_descendants.second.id).to be == @lv1_child_org2.id
47
+ expect(@lv1_child_org.descendants.size).to be == 4
48
+ expect(@lv1_child_org.flat_descendants.size).to be == 8
49
+ expect(@lv1_child_org.flat_descendants.first.id).to be == @lv2_child_org.id
50
+ expect(@lv2_child_org.descendants.size).to be == 3
51
+ end
52
+
53
+ it "s: access ancestors" do
54
+ expect(@root_org.ancestors.size).to be == 1
55
+ expect(@root_org.ancestors.first.id).to be == @root_org.id
56
+ expect(@lv1_child_org.ancestors.size).to be == 1
57
+ expect(@lv1_child_org.ancestors.first.id).to be == @root_org.id
58
+ expect(@lv2_child_org.ancestors.size).to be == 2
59
+ expect(@lv2_child_org.ancestors.first.id).to be == @lv1_child_org.id
60
+ expect(@lv2_child_org.ancestors.second.id).to be == @root_org.id
61
+ expect(@lv5_child_org.ancestors.size).to be == 5
62
+ end
63
+
64
+ it "s: play with history versions" do
65
+ @root_org.as_tree(5.minutes.ago)
66
+
67
+ expect(@root_org.children.size).to be == 1
68
+ expect(@root_org.flat_descendants.size).to be == 2
69
+ expect(@root_org.children.first.children.first.id).to be == @lv1_child_org.id
70
+ expect(@root_org.children.first.children.first.parent.id).to be == @lv2_child_org.id
71
+ end
72
+ end
73
+
74
+ context "Tree Operation" do
75
+ context "Tree is empty" do
76
+ before(:each) do
77
+ @root_org = Org.create(name: 'root')
78
+ end
79
+
80
+ after(:each) do
81
+ @root_org.destroy
82
+ end
83
+
84
+ it "s: add self as the root element" do
85
+ root_org = @root_org.add_as_root
86
+ expect(root_org.tree_empty?).to be_falsy
87
+ expect(root_org.children.size).to be == 0
88
+ expect(root_org.parent?).to be_falsy
89
+ expect(root_org.descendants.size).to be == 0
90
+ expect(root_org.ancestors.size).to be == 1
91
+ end
92
+ end
93
+
94
+ context "Tree isn't empty" do
95
+
96
+ before(:each) do
97
+ init_simple_tree
98
+ @new_org = Org.create(name: 'new')
99
+ @new_org2 = Org.create(name: 'new2')
100
+ end
101
+
102
+ after(:each) do
103
+ destroy_simple_tree
104
+ end
105
+
106
+ context "Self is in the tree" do
107
+ it "f: add self as the root element" do
108
+ expect { @root_org.add_as_root }.to raise_error
109
+ end
110
+
111
+ it "s: add children" do
112
+ @lv1_child_org.add_child(@new_org)
113
+ expect(@lv1_child_org.children.size).to be == 3
114
+ expect(@root_org.flat_descendants.size).to be == 13
115
+ expect(@root_org.descendants.second.size).to be == 5
116
+ end
117
+
118
+ it "f: adding children" do
119
+ expect { @lv1_child_org.add_child(Org.new) }.to raise_error
120
+ expect { @lv1_child_org.add_child(Struct.new) }.to raise_error
121
+ expect { @lv1_child_org.add_child(@lv2_child_org) }.to raise_error
122
+ end
123
+
124
+ it "s: remove self" do
125
+ @lv1_child_org.remove_self
126
+ expect(@lv1_child_org.existed_in_tree?).to be_falsy
127
+ expect(@lv2_child_org.existed_in_tree?).to be_falsy
128
+ expect(@root_org.flat_descendants.size).to be == 3
129
+ end
130
+
131
+ it "s: remove descendants" do
132
+ @lv1_child_org.remove_descendants
133
+ expect(@lv1_child_org.existed_in_tree?).to be_truthy
134
+ expect(@lv2_child_org.existed_in_tree?).to be_falsy
135
+ expect(@root_org.flat_descendants.size).to be == 4
136
+ end
137
+
138
+ it "s: change parent to another object" do
139
+ @lv2_child_org.change_parent(@root_org)
140
+ expect(@lv1_child_org.children.size).to be == 1
141
+ expect(@lv2_child_org.parent.id).to be == @root_org.id
142
+ expect(@lv5_child_org.ancestors.size).to be == 4
143
+ expect(@root_org.children.size).to be == 3
144
+ end
145
+
146
+ it "s: replace root by another object" do
147
+ @root_org.replace_by(@new_org)
148
+ expect(@root_org.existed_in_tree?).to be_falsy
149
+ expect(@lv1_child_org.parent.id).to be == @new_org.id
150
+ expect(@new_org.parent?).to be_falsy
151
+ expect(@new_org.children.size).to be == 2
152
+ expect(@new_org.descendants.size).to be == 5
153
+ end
154
+
155
+ it "s: replace non-root by another object" do
156
+ @lv1_child_org.replace_by(@new_org)
157
+ expect(@lv1_child_org.existed_in_tree?).to be_falsy
158
+ expect(@lv2_child_org.parent.id).to be == @new_org.id
159
+ expect(@new_org.parent.id).to be == @root_org.id
160
+ expect(@root_org.children.size).to be == 2
161
+ expect(@root_org.descendants.size).to be == 5
162
+ end
163
+
164
+ it "f: change parent to another object" do
165
+ expect { @lv1_child_org.change_parent(Org.new) }.to raise_error
166
+ expect { @lv1_child_org.change_parent(Struct.new) }.to raise_error
167
+ expect { @lv1_child_org.change_parent(@new_org) }.to raise_error
168
+ expect { @lv1_child_org.change_parent(@lv2_child_org) }.to raise_error
169
+ expect { @lv1_child_org.change_parent(@lv1_child_org) }.to raise_error
170
+ end
171
+
172
+ it "f: replace self by another object" do
173
+ expect { @lv1_child_org.replace_by(Org.new) }.to raise_error
174
+ expect { @lv1_child_org.replace_by(Struct.new) }.to raise_error
175
+ expect { @lv1_child_org.replace_by(@lv2_child_org) }.to raise_error
176
+ end
177
+
178
+ it "s: play with multiple scopes" do
179
+ # operate with special scope
180
+ @root_org.as_tree('special').add_as_root.add_child(@lv1_child_org)
181
+ @lv1_child_org.add_child(@lv2_child_org4)
182
+
183
+ # force refreshing the timestamp
184
+ @root_org.as_tree('special')
185
+ expect(@root_org.descendants.size).to be == 2
186
+ expect(@lv2_child_org4.parent.id).to be == @lv1_child_org.id
187
+
188
+ # change the scope back to default
189
+ @root_org.as_tree
190
+ @lv2_child_org4.as_tree
191
+ expect(@root_org.flat_descendants.size).to be == 12
192
+ expect(@lv2_child_org4.parent.id).to be == @lv1_child_org2.id
193
+ end
194
+ end
195
+
196
+ context "Self isn't in the tree" do
197
+ it "f: add self as the root element" do
198
+ expect { @new_org.add_as_root }.to raise_error
199
+ end
200
+
201
+ it "f: add children" do
202
+ expect { @new_org.add_child(@new_org2) }.to raise_error
203
+ end
204
+
205
+ it "f: remove self" do
206
+ expect { @new_org.remove_self }.to raise_error
207
+ end
208
+
209
+ it "f: remove descendants" do
210
+ expect { @new_org.remove_descendants }.to raise_error
211
+ end
212
+
213
+ it "f: change parent to another object" do
214
+ expect { @new_org.change_parent(@root_org) }.to raise_error
215
+ end
216
+
217
+ it "f: replace self by another object" do
218
+ expect { @new_org.replace_by(@root_org) }.to raise_error
219
+ end
220
+ end
221
+ end
222
+ end
223
+ end
@@ -0,0 +1,438 @@
1
+ require "codeclimate-test-reporter"
2
+ CodeClimate::TestReporter.start
3
+
4
+ require 'coveralls'
5
+ Coveralls.wear!
6
+
7
+ require 'active_record'
8
+ require 'logger'
9
+
10
+ require 'chronic_tree'
11
+
12
+ # This connection will do for database-independent bug reports.
13
+ ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
14
+ ActiveRecord::Base.logger = Logger.new(STDOUT)
15
+
16
+ # Comment this line to view the debug information in the console.
17
+ ActiveRecord::Base.logger.level = Logger::INFO
18
+
19
+ ActiveRecord::Schema.define do
20
+ create_table :orgs do |t|
21
+ t.string :name
22
+ end
23
+
24
+ create_table :chronic_tree_elements do |t|
25
+ t.string :tree_type, not_null: true
26
+ t.integer :parent_id, not_null: true
27
+ t.integer :child_id, not_null: true
28
+ t.integer :root_id, not_null: true
29
+ t.integer :distance, not_null: true
30
+ t.datetime :start_time, not_null: true
31
+ t.datetime :end_time, not_null: true
32
+ t.string :scope_name, not_null: true
33
+ t.integer :position
34
+
35
+ t.index :tree_type
36
+ t.index :parent_id
37
+ t.index :child_id
38
+ t.index :root_id
39
+ t.index [:start_time, :end_time]
40
+ t.index :scope_name
41
+ end
42
+ end
43
+
44
+ class Org < ActiveRecord::Base
45
+ include ChronicTree
46
+
47
+ chronic_tree
48
+ chronic_tree('special')
49
+ end
50
+
51
+ # Provide a tree with the hierarchy below:
52
+ #
53
+ # Now:
54
+ # root
55
+ # -- lv1
56
+ # -- lv2
57
+ # -- lv3
58
+ # -- lv4
59
+ # -- lv5
60
+ # -- lv2-2
61
+ # -- lv3-2
62
+ # -- lv4-2
63
+ # -- lv5-2
64
+ # -- lv1-2
65
+ # -- lv2-3
66
+ # -- lv2-4
67
+ #
68
+ # 10 minutes ago:
69
+ #
70
+ # root
71
+ # -- lv2
72
+ # -- lv1
73
+ def init_simple_tree
74
+ @root_org = Org.create(name: 'root')
75
+ @lv1_child_org = Org.create(name: 'lv1')
76
+ @lv1_child_org2 = Org.create(name: 'lv1-2')
77
+ @lv2_child_org = Org.create(name: 'lv2')
78
+ @lv2_child_org2 = Org.create(name: 'lv2-2')
79
+ @lv2_child_org3 = Org.create(name: 'lv2-3')
80
+ @lv2_child_org4 = Org.create(name: 'lv2-4')
81
+ @lv3_child_org = Org.create(name: 'lv3')
82
+ @lv3_child_org2 = Org.create(name: 'lv3-2')
83
+ @lv4_child_org = Org.create(name: 'lv4')
84
+ @lv4_child_org2 = Org.create(name: 'lv4-2')
85
+ @lv5_child_org = Org.create(name: 'lv5')
86
+ @lv5_child_org2 = Org.create(name: 'lv5-2')
87
+
88
+ current_time = Time.now
89
+
90
+ @root_org.elements_under_default_root.create(
91
+ parent_id: @root_org.id,
92
+ child_id: @root_org.id,
93
+ distance: 0,
94
+ start_time: 10.minutes.ago(current_time),
95
+ end_time: 1000.years.from_now,
96
+ scope_name: 'default'
97
+ )
98
+
99
+ # 10 minutes ago
100
+ @root_org.elements_under_default_root.create(
101
+ parent_id: @root_org.id,
102
+ child_id: @lv2_child_org.id,
103
+ distance: 1,
104
+ start_time: 10.minutes.ago(current_time),
105
+ end_time: current_time,
106
+ scope_name: 'default'
107
+ )
108
+
109
+ @root_org.elements_under_default_root.create(
110
+ parent_id: @root_org.id,
111
+ child_id: @lv1_child_org.id,
112
+ distance: 2,
113
+ start_time: 10.minutes.ago(current_time),
114
+ end_time: current_time,
115
+ scope_name: 'default'
116
+ )
117
+
118
+ @root_org.elements_under_default_root.create(
119
+ parent_id: @lv2_child_org.id,
120
+ child_id: @lv1_child_org.id,
121
+ distance: 1,
122
+ start_time: 10.minutes.ago(current_time),
123
+ end_time: current_time,
124
+ scope_name: 'default'
125
+ )
126
+
127
+ # now
128
+
129
+ @root_org.elements_under_default_root.create(
130
+ parent_id: @root_org.id,
131
+ child_id: @lv1_child_org.id,
132
+ distance: 1,
133
+ start_time: current_time,
134
+ end_time: 1000.years.since(current_time),
135
+ scope_name: 'default'
136
+ )
137
+
138
+ @root_org.elements_under_default_root.create(
139
+ parent_id: @root_org.id,
140
+ child_id: @lv1_child_org2.id,
141
+ distance: 1,
142
+ start_time: current_time,
143
+ end_time: 1000.years.since(current_time),
144
+ scope_name: 'default'
145
+ )
146
+
147
+ @root_org.elements_under_default_root.create(
148
+ parent_id: @root_org.id,
149
+ child_id: @lv2_child_org.id,
150
+ distance: 2,
151
+ start_time: current_time,
152
+ end_time: 1000.years.since(current_time),
153
+ scope_name: 'default'
154
+ )
155
+
156
+ @root_org.elements_under_default_root.create(
157
+ parent_id: @lv1_child_org.id,
158
+ child_id: @lv2_child_org.id,
159
+ distance: 1,
160
+ start_time: current_time,
161
+ end_time: 1000.years.since(current_time),
162
+ scope_name: 'default'
163
+ )
164
+
165
+ @root_org.elements_under_default_root.create(
166
+ parent_id: @root_org.id,
167
+ child_id: @lv2_child_org2.id,
168
+ distance: 2,
169
+ start_time: current_time,
170
+ end_time: 1000.years.since(current_time),
171
+ scope_name: 'default'
172
+ )
173
+
174
+ @root_org.elements_under_default_root.create(
175
+ parent_id: @lv1_child_org.id,
176
+ child_id: @lv2_child_org2.id,
177
+ distance: 1,
178
+ start_time: current_time,
179
+ end_time: 1000.years.since(current_time),
180
+ scope_name: 'default'
181
+ )
182
+
183
+ @root_org.elements_under_default_root.create(
184
+ parent_id: @root_org.id,
185
+ child_id: @lv2_child_org3.id,
186
+ distance: 2,
187
+ start_time: current_time,
188
+ end_time: 1000.years.since(current_time),
189
+ scope_name: 'default'
190
+ )
191
+
192
+ @root_org.elements_under_default_root.create(
193
+ parent_id: @lv1_child_org2.id,
194
+ child_id: @lv2_child_org3.id,
195
+ distance: 1,
196
+ start_time: current_time,
197
+ end_time: 1000.years.since(current_time),
198
+ scope_name: 'default'
199
+ )
200
+
201
+ @root_org.elements_under_default_root.create(
202
+ parent_id: @root_org.id,
203
+ child_id: @lv2_child_org4.id,
204
+ distance: 2,
205
+ start_time: current_time,
206
+ end_time: 1000.years.since(current_time),
207
+ scope_name: 'default'
208
+ )
209
+
210
+ @root_org.elements_under_default_root.create(
211
+ parent_id: @lv1_child_org2.id,
212
+ child_id: @lv2_child_org4.id,
213
+ distance: 1,
214
+ start_time: current_time,
215
+ end_time: 1000.years.since(current_time),
216
+ scope_name: 'default'
217
+ )
218
+
219
+ @root_org.elements_under_default_root.create(
220
+ parent_id: @root_org.id,
221
+ child_id: @lv3_child_org.id,
222
+ distance: 3,
223
+ start_time: current_time,
224
+ end_time: 1000.years.since(current_time),
225
+ scope_name: 'default'
226
+ )
227
+
228
+ @root_org.elements_under_default_root.create(
229
+ parent_id: @lv1_child_org.id,
230
+ child_id: @lv3_child_org.id,
231
+ distance: 2,
232
+ start_time: current_time,
233
+ end_time: 1000.years.since(current_time),
234
+ scope_name: 'default'
235
+ )
236
+
237
+ @root_org.elements_under_default_root.create(
238
+ parent_id: @lv2_child_org.id,
239
+ child_id: @lv3_child_org.id,
240
+ distance: 1,
241
+ start_time: current_time,
242
+ end_time: 1000.years.since(current_time),
243
+ scope_name: 'default'
244
+ )
245
+
246
+ @root_org.elements_under_default_root.create(
247
+ parent_id: @root_org.id,
248
+ child_id: @lv4_child_org.id,
249
+ distance: 4,
250
+ start_time: current_time,
251
+ end_time: 1000.years.since(current_time),
252
+ scope_name: 'default'
253
+ )
254
+
255
+ @root_org.elements_under_default_root.create(
256
+ parent_id: @lv1_child_org.id,
257
+ child_id: @lv4_child_org.id,
258
+ distance: 3,
259
+ start_time: current_time,
260
+ end_time: 1000.years.since(current_time),
261
+ scope_name: 'default'
262
+ )
263
+
264
+ @root_org.elements_under_default_root.create(
265
+ parent_id: @lv2_child_org.id,
266
+ child_id: @lv4_child_org.id,
267
+ distance: 2,
268
+ start_time: current_time,
269
+ end_time: 1000.years.since(current_time),
270
+ scope_name: 'default'
271
+ )
272
+
273
+ @root_org.elements_under_default_root.create(
274
+ parent_id: @lv3_child_org.id,
275
+ child_id: @lv4_child_org.id,
276
+ distance: 1,
277
+ start_time: current_time,
278
+ end_time: 1000.years.since(current_time),
279
+ scope_name: 'default'
280
+ )
281
+
282
+ @root_org.elements_under_default_root.create(
283
+ parent_id: @root_org.id,
284
+ child_id: @lv5_child_org.id,
285
+ distance: 5,
286
+ start_time: current_time,
287
+ end_time: 1000.years.since(current_time),
288
+ scope_name: 'default'
289
+ )
290
+
291
+ @root_org.elements_under_default_root.create(
292
+ parent_id: @lv1_child_org.id,
293
+ child_id: @lv5_child_org.id,
294
+ distance: 4,
295
+ start_time: current_time,
296
+ end_time: 1000.years.since(current_time),
297
+ scope_name: 'default'
298
+ )
299
+
300
+ @root_org.elements_under_default_root.create(
301
+ parent_id: @lv2_child_org.id,
302
+ child_id: @lv5_child_org.id,
303
+ distance: 3,
304
+ start_time: current_time,
305
+ end_time: 1000.years.since(current_time),
306
+ scope_name: 'default'
307
+ )
308
+
309
+ @root_org.elements_under_default_root.create(
310
+ parent_id: @lv3_child_org.id,
311
+ child_id: @lv5_child_org.id,
312
+ distance: 2,
313
+ start_time: current_time,
314
+ end_time: 1000.years.since(current_time),
315
+ scope_name: 'default'
316
+ )
317
+
318
+ @root_org.elements_under_default_root.create(
319
+ parent_id: @lv4_child_org.id,
320
+ child_id: @lv5_child_org.id,
321
+ distance: 1,
322
+ start_time: current_time,
323
+ end_time: 1000.years.since(current_time),
324
+ scope_name: 'default'
325
+ )
326
+
327
+ @root_org.elements_under_default_root.create(
328
+ parent_id: @root_org.id,
329
+ child_id: @lv3_child_org2.id,
330
+ distance: 3,
331
+ start_time: current_time,
332
+ end_time: 1000.years.since(current_time),
333
+ scope_name: 'default'
334
+ )
335
+
336
+ @root_org.elements_under_default_root.create(
337
+ parent_id: @lv1_child_org.id,
338
+ child_id: @lv3_child_org2.id,
339
+ distance: 2,
340
+ start_time: current_time,
341
+ end_time: 1000.years.since(current_time),
342
+ scope_name: 'default'
343
+ )
344
+
345
+ @root_org.elements_under_default_root.create(
346
+ parent_id: @lv2_child_org2.id,
347
+ child_id: @lv3_child_org2.id,
348
+ distance: 1,
349
+ start_time: current_time,
350
+ end_time: 1000.years.since(current_time),
351
+ scope_name: 'default'
352
+ )
353
+
354
+ @root_org.elements_under_default_root.create(
355
+ parent_id: @root_org.id,
356
+ child_id: @lv4_child_org2.id,
357
+ distance: 4,
358
+ start_time: current_time,
359
+ end_time: 1000.years.since(current_time),
360
+ scope_name: 'default'
361
+ )
362
+
363
+ @root_org.elements_under_default_root.create(
364
+ parent_id: @lv1_child_org.id,
365
+ child_id: @lv4_child_org2.id,
366
+ distance: 3,
367
+ start_time: current_time,
368
+ end_time: 1000.years.since(current_time),
369
+ scope_name: 'default'
370
+ )
371
+
372
+ @root_org.elements_under_default_root.create(
373
+ parent_id: @lv2_child_org2.id,
374
+ child_id: @lv4_child_org2.id,
375
+ distance: 2,
376
+ start_time: current_time,
377
+ end_time: 1000.years.since(current_time),
378
+ scope_name: 'default'
379
+ )
380
+
381
+ @root_org.elements_under_default_root.create(
382
+ parent_id: @lv3_child_org2.id,
383
+ child_id: @lv4_child_org2.id,
384
+ distance: 1,
385
+ start_time: current_time,
386
+ end_time: 1000.years.since(current_time),
387
+ scope_name: 'default'
388
+ )
389
+
390
+ @root_org.elements_under_default_root.create(
391
+ parent_id: @root_org.id,
392
+ child_id: @lv5_child_org2.id,
393
+ distance: 5,
394
+ start_time: current_time,
395
+ end_time: 1000.years.since(current_time),
396
+ scope_name: 'default'
397
+ )
398
+
399
+ @root_org.elements_under_default_root.create(
400
+ parent_id: @lv1_child_org.id,
401
+ child_id: @lv5_child_org2.id,
402
+ distance: 4,
403
+ start_time: current_time,
404
+ end_time: 1000.years.since(current_time),
405
+ scope_name: 'default'
406
+ )
407
+
408
+ @root_org.elements_under_default_root.create(
409
+ parent_id: @lv2_child_org2.id,
410
+ child_id: @lv5_child_org2.id,
411
+ distance: 3,
412
+ start_time: current_time,
413
+ end_time: 1000.years.since(current_time),
414
+ scope_name: 'default'
415
+ )
416
+
417
+ @root_org.elements_under_default_root.create(
418
+ parent_id: @lv3_child_org2.id,
419
+ child_id: @lv5_child_org2.id,
420
+ distance: 2,
421
+ start_time: current_time,
422
+ end_time: 1000.years.since(current_time),
423
+ scope_name: 'default'
424
+ )
425
+
426
+ @root_org.elements_under_default_root.create(
427
+ parent_id: @lv4_child_org2.id,
428
+ child_id: @lv5_child_org2.id,
429
+ distance: 1,
430
+ start_time: current_time,
431
+ end_time: 1000.years.since(current_time),
432
+ scope_name: 'default'
433
+ )
434
+ end
435
+
436
+ def destroy_simple_tree
437
+ Org.destroy_all
438
+ end