chronic_tree 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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