treeable 0.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.
- checksums.yaml +7 -0
- data/lib/treeable.rb +127 -0
- metadata +45 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 85fb68955146f887d08b6ca36529664c4b60cd2c
|
4
|
+
data.tar.gz: 7a0b4bb89f1306bbe67cf8eabcc01edeafc0a7bc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a2d5c679d50d3921f2d499d008642c68766317db3eb93781f6d67eeef61b5451998e0023377a363aca31f24a96f0a9426b9717e7e58ac2fd5d823caa636a7ed3
|
7
|
+
data.tar.gz: f13ecadad4ccdf7c2b80fa6c498d59a59d96e4d7eb650f250e9fffe24a9867aa833fd9d215cc43fafae6c390397a959e917eb76963ca610b555dcea40c491752
|
data/lib/treeable.rb
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
module Treeable
|
2
|
+
extend ::ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
|
6
|
+
after_create :update_path
|
7
|
+
after_update :repopulate_path
|
8
|
+
belongs_to :parent, :class_name => self.to_s, :foreign_key => :parent_id
|
9
|
+
has_many :children, :class_name => self.to_s, :foreign_key=> :parent_id
|
10
|
+
|
11
|
+
@treeable_parent = :parent_id
|
12
|
+
@treeable_path = :path
|
13
|
+
|
14
|
+
def self.define_association
|
15
|
+
belongs_to :parent, :class_name => self.to_s, :foreign_key => @treeable_parent
|
16
|
+
has_many :children, :class_name => self.to_s, :foreign_key=> @treeable_parent
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.treeable_path_column(column_name=nil)
|
20
|
+
if column_name
|
21
|
+
@treeable_path = column_name.to_sym
|
22
|
+
end
|
23
|
+
return @treeable_path
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def self.treeable_parent_column(column_name=nil)
|
28
|
+
if column_name
|
29
|
+
@treeable_parent = column_name.to_sym
|
30
|
+
self.define_association
|
31
|
+
end
|
32
|
+
return @treeable_parent
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.json_tree(nodes)
|
36
|
+
nodes.map do |node|
|
37
|
+
{:id => node.id, :children => json_tree(node.children)}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.roots
|
42
|
+
where(@treeable_parent => nil)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.leaves
|
46
|
+
array = []
|
47
|
+
roots.each do |k|
|
48
|
+
array += k.leafs
|
49
|
+
end
|
50
|
+
self.where(id: (array.uniq.compact))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def path
|
55
|
+
if !self.attributes.keys.include?("path") && self.class.treeable_path_column !="path"
|
56
|
+
send(self.class.treeable_path_column)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def is_leaf
|
61
|
+
self.children.empty?
|
62
|
+
end
|
63
|
+
|
64
|
+
def is_root
|
65
|
+
self.parent.blank?
|
66
|
+
end
|
67
|
+
|
68
|
+
def parent_map(&block)
|
69
|
+
(nodes_from_root || []).each{|k| block.call k}
|
70
|
+
end
|
71
|
+
|
72
|
+
def children_map(&block)
|
73
|
+
unless all_children.empty?
|
74
|
+
children.each{|k| k.children_map(&block)}
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def leafs
|
79
|
+
array = []
|
80
|
+
if self.is_leaf
|
81
|
+
array << self.id
|
82
|
+
else
|
83
|
+
parent_ids = self.all_children.where(self.class.treeable_parent_column => (all_children_ids << self.id)).pluck(self.class.treeable_parent_column)
|
84
|
+
array += self.all_children_ids - parent_ids
|
85
|
+
end
|
86
|
+
array
|
87
|
+
end
|
88
|
+
|
89
|
+
def leaf_nodes
|
90
|
+
internal_nodes = self.class.where(self.class.treeable_parent_column => self.all_children_ids).select(self.class.treeable_parent_column).group(self.class.treeable_parent_column).pluck(self.class.treeable_parent_column)
|
91
|
+
self.all_children.map{|t| t unless internal_nodes.include?(t[:id])}.uniq.compact
|
92
|
+
end
|
93
|
+
|
94
|
+
def node_ids_from_root
|
95
|
+
self.path.split(".").map{|k| k.to_i}
|
96
|
+
end
|
97
|
+
|
98
|
+
def nodes_from_root
|
99
|
+
self.class.where(:id => node_ids_from_root).order("length(#{self.class.treeable_path_column.to_s}) ASC")
|
100
|
+
end
|
101
|
+
|
102
|
+
def all_children
|
103
|
+
self.class.where("#{self.class.treeable_path_column} LIKE '#{self.path}%'").where.not(:id => self.id)
|
104
|
+
end
|
105
|
+
|
106
|
+
def all_children_ids
|
107
|
+
all_children.pluck(:id)
|
108
|
+
end
|
109
|
+
|
110
|
+
def repopulate_path
|
111
|
+
if self.parent_id_changed?
|
112
|
+
child_nodes = all_children
|
113
|
+
path = parent ? "#{parent.path}#{self.id}." : "#{self.id}."
|
114
|
+
self.update_column(self.class.treeable_path_column.to_s, path)
|
115
|
+
child_nodes.each{|k| k.update_path}
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def update_path
|
120
|
+
new_path = self.parent ? "#{self.parent.path}#{self.id}." : "#{self.id}."
|
121
|
+
self.update_column(self.class.treeable_path_column.to_s, new_path)
|
122
|
+
end
|
123
|
+
|
124
|
+
def root
|
125
|
+
self.path.split('.').first.to_i
|
126
|
+
end
|
127
|
+
end
|
metadata
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: treeable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Saurav Swaroop
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-04-14 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A simple hello world gem
|
14
|
+
email: swaroop.saurav.s@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/treeable.rb
|
20
|
+
homepage: http://rubygems.org/gems/hola
|
21
|
+
licenses:
|
22
|
+
- MIT
|
23
|
+
metadata: {}
|
24
|
+
post_install_message:
|
25
|
+
rdoc_options: []
|
26
|
+
require_paths:
|
27
|
+
- lib
|
28
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
requirements: []
|
39
|
+
rubyforge_project:
|
40
|
+
rubygems_version: 2.6.12
|
41
|
+
signing_key:
|
42
|
+
specification_version: 4
|
43
|
+
summary: Making any Rails model treeable. Any model is Treeable if it has parent chuld
|
44
|
+
relation with itself
|
45
|
+
test_files: []
|