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: 3cb8cb8fc8407e775471c6e4ebfd45f594a7f7dc
4
- data.tar.gz: c97fbb287fa63b841e513e7ec2f2e084c02d5fee
3
+ metadata.gz: fd3f337c1418d33c73887add48d5bec679c4dc93
4
+ data.tar.gz: a6e945638bc2e2351b76aa196a55c3e42a29f00c
5
5
  SHA512:
6
- metadata.gz: 8e75e496a3ffdf8df6ba1f40051239c9d82f5354e5f12ee35b42316c435be014fb15d8690ecb4d1b39681514628f0fa20ef12d9f975aeaf3d4ef31e5999546ae
7
- data.tar.gz: f637a0a366f57560efa691fa86a58f8ddb800e21ac437c34ac194d3b663d31da74e6acba57e23087bc852aa28e147e0f2e6a75b1585b49097b44de8153ee2199
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(ancestor_id: nil))
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=(new_parent,hierarchy_scope='')
50
- hierarchy_class.set_parent_of(self,new_parent,hierarchy_scope)
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
- .on(t1[:ancestor_id]
29
- .eq(t2[:descendant_id])
30
- .and(t1[:hierarchy_scope].eq(t2[:hierarchy_scope])
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.fill_in_ancestors_for(new_parent,item,hierarchy_scope)
41
- self.delete_ancestors_of_item_children(item,hierarchy_scope)
42
- self.set_new_ancestors_of_item_children(item,hierarchy_scope)
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,it.hierarchy_scope
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,#{item.id},it.generation+1,it.hierarchy_scope
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
- where it.descendant_id=#{new_parent.id}
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
@@ -1,3 +1,3 @@
1
1
  module ActsAsManyTrees
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -1,4 +1,5 @@
1
1
  class <%= migration_class_name %> < ActiveRecord::Migration
2
+ #[TO DO], if schema_plus is installed then we have to change the table the foreign keys look for
2
3
  def change
3
4
  create_table :<%= hierarchy_table_name %>, id: false do |t|
4
5
  t.integer :ancestor_id, null: false
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_many_trees
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Small