acts_as_many_trees 0.0.2 → 0.0.3

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.
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