acts_as_many_trees 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd3f337c1418d33c73887add48d5bec679c4dc93
|
4
|
+
data.tar.gz: a6e945638bc2e2351b76aa196a55c3e42a29f00c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ea378e205fa97476047c31a321d1af3a5ba268ce2152e1cb7e5de7e98db79461ede251b36503aac1d5cef484081eeb7f02b6108ec0d94ebde1e7b3aca5d588f
|
7
|
+
data.tar.gz: 0df35bdfc480744e0f89d2f48f666c86415e171946ff6e00ee07d18eb06518c4a0bf2565579bbac7e88028402953ad61f5c49d5fba64ee4f327eedbf1c933f3c
|
@@ -25,16 +25,19 @@ module ActsAsManyTrees
|
|
25
25
|
extend ActiveSupport::Concern
|
26
26
|
included do
|
27
27
|
has_many :unscoped_descendant_links,
|
28
|
+
->{order(:position)},
|
28
29
|
class_name:hierarchy_class.to_s,
|
29
30
|
foreign_key: 'ancestor_id',
|
30
31
|
dependent: :delete_all,
|
31
32
|
inverse_of: :unscoped_ancestor
|
32
33
|
|
33
34
|
has_many :unscoped_ancestor_links,
|
35
|
+
->{order(:position)},
|
34
36
|
class_name: hierarchy_class.to_s,
|
35
37
|
foreign_key: 'descendant_id',
|
36
38
|
dependent: :delete_all,
|
37
39
|
inverse_of: :unscoped_descendant
|
40
|
+
|
38
41
|
has_many :unscoped_ancestors,through: :unscoped_ancestor_links
|
39
42
|
has_many :unscoped_descendants, through: :unscoped_descendant_links
|
40
43
|
scope :roots , ->(hierarchy=''){
|
@@ -42,18 +45,31 @@ module ActsAsManyTrees
|
|
42
45
|
.and(hierarchy_class.arel_table[:hierarchy_scope].eq(hierarchy))
|
43
46
|
)
|
44
47
|
outer_join = Arel::Nodes::OuterJoin.new(hierarchy_class.arel_table,on)
|
45
|
-
joins(outer_join).merge(hierarchy_class.where(
|
48
|
+
joins(outer_join).merge(hierarchy_class.where(generation: 0))
|
46
49
|
}
|
47
50
|
end
|
48
51
|
delegate :hierarchy_class, to: :class
|
49
|
-
def parent=(
|
50
|
-
|
52
|
+
def parent=(inpt_parent)
|
53
|
+
if inpt_parent.is_a?(Hash)
|
54
|
+
new_parent=inpt_parent[:new_parent]
|
55
|
+
after_node=inpt_parent[:after_node]
|
56
|
+
before_node=inpt_parent[:before_node]
|
57
|
+
hierarchy_scope=inpt_parent[:hierarchy_scope] || ''
|
58
|
+
else
|
59
|
+
new_parent=inpt_parent
|
60
|
+
hierarchy_scope = ''
|
61
|
+
end
|
62
|
+
hierarchy_class.set_parent_of(self,new_parent,hierarchy_scope,after_node,before_node)
|
51
63
|
end
|
52
64
|
|
53
65
|
def set_parent(new_parent,hierarchy_scope='')
|
54
66
|
hierarchy_class.set_parent_of(self,new_parent,hierarchy_scope)
|
55
67
|
end
|
56
68
|
|
69
|
+
def add_child(new_child,hierarchy_scope='')
|
70
|
+
hierarchy_class.set_parent_of(new_child,self,hierarchy_scope)
|
71
|
+
end
|
72
|
+
|
57
73
|
def parent(hierarchy_scope='')
|
58
74
|
ancestors(hierarchy_scope).where('generation=1').first
|
59
75
|
end
|
@@ -62,6 +78,15 @@ module ActsAsManyTrees
|
|
62
78
|
descendants(hierarchy_scope).where('generation=1')
|
63
79
|
end
|
64
80
|
|
81
|
+
def siblings(hierarchy_scope='')
|
82
|
+
parent(hierarchy_scope).children(hierarchy_scope).where.not(id: id)
|
83
|
+
end
|
84
|
+
|
85
|
+
def self_and_siblings(hierarchy_scope='')
|
86
|
+
parent(hierarchy_scope).children(hierarchy_scope)
|
87
|
+
end
|
88
|
+
|
89
|
+
|
65
90
|
def ancestors(hierarchy='')
|
66
91
|
unscoped_ancestors.merge(hierarchy_class.scope_hierarchy(hierarchy))
|
67
92
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require 'bigdecimal'
|
2
2
|
module ActsAsManyTrees
|
3
3
|
module HierarchyTable
|
4
4
|
extend ActiveSupport::Concern
|
@@ -25,26 +25,27 @@ module ActsAsManyTrees
|
|
25
25
|
t1 = arel_table
|
26
26
|
t2 = arel_table.alias
|
27
27
|
t1.project(Arel::star).join(t2,Arel::Nodes::OuterJoin)
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
)
|
32
|
-
)
|
33
|
-
.where(t2[:ancestor_id].eq(nil)
|
28
|
+
.on(t1[:ancestor_id]
|
29
|
+
.eq(t2[:descendant_id])
|
30
|
+
.and(t1[:hierarchy_scope].eq(t2[:hierarchy_scope])
|
34
31
|
)
|
35
|
-
|
32
|
+
)
|
33
|
+
.where(t2[:ancestor_id].eq(nil)
|
34
|
+
)
|
35
|
+
|
36
36
|
end
|
37
37
|
|
38
|
-
def self.set_parent_of(item,new_parent,hierarchy_scope='')
|
39
|
-
self.delete_ancestors(item,hierarchy_scope)
|
40
|
-
self.
|
41
|
-
self.
|
42
|
-
self.
|
38
|
+
def self.set_parent_of(item,new_parent,hierarchy_scope='',after_node=nil,before_node=nil)
|
39
|
+
self.delete_ancestors(item,hierarchy_scope) if item
|
40
|
+
self.fill_in_parent_for(new_parent,item,hierarchy_scope,after_node,before_node) if item || new_parent
|
41
|
+
self.fill_in_ancestors_for(new_parent,item,hierarchy_scope) if item && new_parent
|
42
|
+
self.delete_ancestors_of_item_children(item,hierarchy_scope) if item
|
43
|
+
self.set_new_ancestors_of_item_children(item,hierarchy_scope) if item
|
43
44
|
end
|
44
45
|
|
45
46
|
private
|
46
47
|
def self.delete_ancestors(item,hierarchy_scope)
|
47
|
-
delete_all(descendant_id: item.id,hierarchy_scope: hierarchy_scope)
|
48
|
+
delete_all(descendant_id: item.id,hierarchy_scope: hierarchy_scope )
|
48
49
|
end
|
49
50
|
|
50
51
|
def self.delete_ancestors_of_item_children(item,hierarchy_scope)
|
@@ -61,8 +62,8 @@ module ActsAsManyTrees
|
|
61
62
|
|
62
63
|
def self.set_new_ancestors_of_item_children(item,hierarchy_scope)
|
63
64
|
sql=<<-SQL
|
64
|
-
insert into #{table_name}(ancestor_id,descendant_id,generation,hierarchy_scope)
|
65
|
-
select it.ancestor_id,ct.descendant_id,it.generation+ct.generation,
|
65
|
+
insert into #{table_name}(ancestor_id,descendant_id,generation,hierarchy_scope,position)
|
66
|
+
select it.ancestor_id,ct.descendant_id,it.generation+ct.generation,ct.hierarchy_scope,ct.position
|
66
67
|
from #{table_name} it
|
67
68
|
join #{table_name} ct
|
68
69
|
on ct.ancestor_id = it.descendant_id
|
@@ -73,19 +74,65 @@ module ActsAsManyTrees
|
|
73
74
|
connection.execute(sql)
|
74
75
|
end
|
75
76
|
|
77
|
+
def self.fill_in_parent_for(new_parent,item,hierarchy_scope='',after_node=nil,before_node=nil)
|
78
|
+
if new_parent
|
79
|
+
p_rec = find_by(descendant_id: new_parent.id,hierarchy_scope: hierarchy_scope)
|
80
|
+
unless p_rec
|
81
|
+
p_rec=create!(ancestor_id: new_parent.id,descendant_id: new_parent.id,hierarchy_scope: hierarchy_scope,generation:0,position:Random.rand(1000000))
|
82
|
+
end
|
83
|
+
# p "p_rec.position = #{p_rec.position}"
|
84
|
+
a_rec = nil
|
85
|
+
if after_node
|
86
|
+
a_rec = after_node
|
87
|
+
a_rec_h = find_by(ancestor_id: new_parent.id, descendant_id:a_rec.id,hierarchy_scope: hierarchy_scope)
|
88
|
+
a_rec_pos = a_rec_h.position
|
89
|
+
elsif new_parent.children.last
|
90
|
+
a_rec = new_parent.children.last
|
91
|
+
a_rec_h = find_by(ancestor_id: new_parent.id, descendant_id:a_rec.id,hierarchy_scope: hierarchy_scope)
|
92
|
+
a_rec_pos = a_rec_h.position
|
93
|
+
else
|
94
|
+
a_rec_pos = p_rec.position
|
95
|
+
end
|
96
|
+
|
97
|
+
if before_node
|
98
|
+
b_rec = find_by(descendant_id: before_node.id,hierarchy_scope: hierarchy_scope,generation: 1)
|
99
|
+
if b_rec
|
100
|
+
b_position = b_rec.position
|
101
|
+
end
|
102
|
+
end
|
103
|
+
if b_position && !after_node
|
104
|
+
# p "b_position #{b_position} parent position #{p_rec.position}"
|
105
|
+
new_position = (Random.rand(10)*(b_position - p_rec.position)/11)+p_rec.position
|
106
|
+
elsif b_position && after_node
|
107
|
+
# p "b_position #{b_position} after position #{a_rec_pos}"
|
108
|
+
new_position = (Random.rand(10)*(b_position - a_rec_pos)/11)+a_rec_pos
|
109
|
+
else
|
110
|
+
new_position = a_rec_pos + Random.rand(1000000)
|
111
|
+
end
|
112
|
+
#create(ancestor_id: item.id,descendant_id: item.id,hierarchy_scope: hierarchy_scope,position:new_position,generation:0)
|
113
|
+
if item
|
114
|
+
# p "id = #{item.id} position=#{new_position}"
|
115
|
+
create(ancestor_id: new_parent.id,descendant_id: item.id,generation: 1,hierarchy_scope: hierarchy_scope,position:new_position)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
76
120
|
def self.fill_in_ancestors_for(new_parent,item,hierarchy_scope)
|
77
121
|
if new_parent
|
78
|
-
create(ancestor_id: new_parent.id,descendant_id: item.id,generation: 1,hierarchy_scope: hierarchy_scope)
|
79
122
|
sql=<<-SQL
|
80
|
-
insert into #{table_name}(ancestor_id,descendant_id,generation,hierarchy_scope)
|
81
|
-
select it.ancestor_id
|
123
|
+
insert into #{table_name}(ancestor_id,descendant_id,generation,hierarchy_scope,position)
|
124
|
+
select it.ancestor_id,new_itm.descendant_id,it.generation+1,it.hierarchy_scope,new_itm.position
|
82
125
|
from #{table_name} it
|
83
|
-
|
126
|
+
join #{table_name} new_itm on it.descendant_id = new_itm.ancestor_id and it.hierarchy_scope=new_itm.hierarchy_scope
|
127
|
+
where new_itm.ancestor_id=#{new_parent.id}
|
128
|
+
and new_itm.descendant_id=#{item.id}
|
129
|
+
and (it.ancestor_id <> it.descendant_id)
|
84
130
|
and it.hierarchy_scope = '#{hierarchy_scope}'
|
85
131
|
SQL
|
86
132
|
ActiveRecord::Base.connection.execute(sql)
|
87
133
|
end
|
88
134
|
end
|
135
|
+
|
89
136
|
end
|
90
137
|
end
|
91
138
|
end
|