summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Gemfile3
-rw-r--r--Gemfile.lock10
-rw-r--r--app/controllers/admin_controller.rb8
-rw-r--r--app/models/concerns/nested_tree.rb86
-rw-r--r--app/models/node.rb25
-rw-r--r--db/seeds/chapters.rb3
6 files changed, 95 insertions, 40 deletions
diff --git a/Gemfile b/Gemfile
index 13bb4ca..d136eb5 100644
--- a/Gemfile
+++ b/Gemfile
@@ -44,9 +44,6 @@ gem 'will_paginate', '~> 3.0'
44gem 'acts-as-taggable-on', 44gem 'acts-as-taggable-on',
45 git: 'https://github.com/mbleigh/acts-as-taggable-on.git', 45 git: 'https://github.com/mbleigh/acts-as-taggable-on.git',
46 branch: 'master' 46 branch: 'master'
47gem 'awesome_nested_set',
48 git: 'https://github.com/collectiveidea/awesome_nested_set.git',
49 branch: 'main'
50 47
51# ── XML / parsing ───────────────────────────────────────────────────────────── 48# ── XML / parsing ─────────────────────────────────────────────────────────────
52 49
diff --git a/Gemfile.lock b/Gemfile.lock
index 2e9a1ce..02c71ff 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,12 +1,4 @@
1GIT 1GIT
2 remote: https://github.com/collectiveidea/awesome_nested_set.git
3 revision: 7a642749af74519b4bf3642d939061beb36835e1
4 branch: main
5 specs:
6 awesome_nested_set (3.9.0)
7 activerecord (>= 4.0.0, < 8.2)
8
9GIT
10 remote: https://github.com/erdgeist/chaoscalendar.git 2 remote: https://github.com/erdgeist/chaoscalendar.git
11 revision: 48fe5c517ae3895cc78d9d2fefbdd35b90d52ba7 3 revision: 48fe5c517ae3895cc78d9d2fefbdd35b90d52ba7
12 branch: erdgeist-ruby1.9 4 branch: erdgeist-ruby1.9
@@ -335,7 +327,6 @@ PLATFORMS
335DEPENDENCIES 327DEPENDENCIES
336 acts-as-taggable-on! 328 acts-as-taggable-on!
337 acts_as_list 329 acts_as_list
338 awesome_nested_set!
339 chaos_calendar! 330 chaos_calendar!
340 coffee-rails (~> 4.0) 331 coffee-rails (~> 4.0)
341 concurrent-ruby (~> 1.3) 332 concurrent-ruby (~> 1.3)
@@ -374,7 +365,6 @@ CHECKSUMS
374 activesupport (8.1.3) sha256=21a5e0dfbd4c3ddd9e1317ec6a4d782fa226e7867dc70b0743acda81a1dca20e 365 activesupport (8.1.3) sha256=21a5e0dfbd4c3ddd9e1317ec6a4d782fa226e7867dc70b0743acda81a1dca20e
375 acts-as-taggable-on (13.0.0) 366 acts-as-taggable-on (13.0.0)
376 acts_as_list (1.2.6) sha256=8345380900b7bee620c07ad00991ccee59af3d8c9e8574f426e321da2865fdc8 367 acts_as_list (1.2.6) sha256=8345380900b7bee620c07ad00991ccee59af3d8c9e8574f426e321da2865fdc8
377 awesome_nested_set (3.9.0)
378 base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b 368 base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
379 bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd 369 bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd
380 builder (3.3.0) sha256=497918d2f9dca528fdca4b88d84e4ef4387256d984b8154e9d5d3fe5a9c8835f 370 builder (3.3.0) sha256=497918d2f9dca528fdca4b88d84e4ef4387256d984b8154e9d5d3fe5a9c8835f
diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb
index bfc6cd8..3fa0519 100644
--- a/app/controllers/admin_controller.rb
+++ b/app/controllers/admin_controller.rb
@@ -15,12 +15,10 @@ class AdminController < ApplicationController
15 Time.now, Time.now - 14.days 15 Time.now, Time.now - 14.days
16 ).limit(50).order("updated_at desc") 16 ).limit(50).order("updated_at desc")
17 17
18 all_nodes = Node.root.self_and_descendants 18 ordered_with_level = Node.root.self_and_descendants_ordered_with_level
19 @sitemap_depth = {} 19 @sitemap_depth = {}
20 Node.each_with_level(all_nodes) do |node, level| 20 ordered_with_level.each { |node, level| @sitemap_depth[node.id] = level }
21 @sitemap_depth[node.id] = level 21 @sitemap = ordered_with_level.map(&:first).reject(&:update?)
22 end
23 @sitemap = all_nodes.to_a.sort! { |node1,node2| node1.lft <=> node2.lft }.delete_if { |node| node.update? }
24 22
25 @mypages = Page.where("user_id = ? or editor_id = ?", @current_user, @current_user) 23 @mypages = Page.where("user_id = ? or editor_id = ?", @current_user, @current_user)
26 24
diff --git a/app/models/concerns/nested_tree.rb b/app/models/concerns/nested_tree.rb
new file mode 100644
index 0000000..9a2eb0e
--- /dev/null
+++ b/app/models/concerns/nested_tree.rb
@@ -0,0 +1,86 @@
1# app/models/concerns/nested_tree.rb
2#
3# Minimal parent_id-based replacement for the tree-traversal subset of
4# awesome_nested_set actually used by this app (descendants, ancestors,
5# level, root, move_to_child_of)
6module NestedTree
7 extend ActiveSupport::Concern
8
9 included do
10 belongs_to :parent, class_name: name, foreign_key: :parent_id, optional: true, inverse_of: :children
11 has_many :children, -> { order(:id) }, class_name: name, foreign_key: :parent_id, inverse_of: :parent
12
13 before_destroy :delete_descendants
14 end
15
16 class_methods do
17 def root
18 roots.first
19 end
20
21 def roots
22 where(parent_id: nil)
23 end
24
25 def valid?
26 # Every non-root row's parent_id must point at a real, existing row.
27 where.not(parent_id: nil).where.missing(:parent).none?
28 end
29 end
30
31 def root?
32 parent_id.nil?
33 end
34
35 def ancestors
36 result = []
37 current = parent
38 while current
39 result << current
40 current = current.parent
41 end
42 result
43 end
44
45 def level
46 ancestors.size
47 end
48
49 def descendants
50 ids = []
51 queue = self.class.where(parent_id: id).pluck(:id)
52 until queue.empty?
53 ids.concat(queue)
54 queue = self.class.where(parent_id: queue).pluck(:id)
55 end
56 self.class.where(id: ids)
57 end
58
59 def self_and_descendants
60 self.class.where(id: [id] + descendants.pluck(:id))
61 end
62
63 def self_and_descendants_ordered_with_level
64 nodes = [self] + descendants.to_a
65 children_by_parent = nodes.group_by(&:parent_id)
66 children_by_parent.each_value { |list| list.sort_by!(&:id) }
67
68 result = []
69 visit = ->(node, level) do
70 result << [node, level]
71 (children_by_parent[node.id] || []).each { |child| visit.call(child, level + 1) }
72 end
73 visit.call(self, 0)
74 result
75 end
76
77 def move_to_child_of(new_parent)
78 update!(parent_id: new_parent.id)
79 end
80
81 private
82
83 def delete_descendants
84 self.class.where(id: descendants.pluck(:id)).delete_all
85 end
86end
diff --git a/app/models/node.rb b/app/models/node.rb
index 2177f15..fc23dc1 100644
--- a/app/models/node.rb
+++ b/app/models/node.rb
@@ -1,6 +1,6 @@
1class Node < ApplicationRecord 1class Node < ApplicationRecord
2 # Mixins and Plugins 2 # Mixins and Plugins
3 acts_as_nested_set 3 include NestedTree
4 4
5 # Associations 5 # Associations
6 has_many :pages, -> { order("revision ASC") }, :dependent => :destroy 6 has_many :pages, -> { order("revision ASC") }, :dependent => :destroy
@@ -21,16 +21,6 @@ class Node < ApplicationRecord
21 validates_uniqueness_of :slug, :scope => :parent_id, :unless => -> { parent_id.nil? } 21 validates_uniqueness_of :slug, :scope => :parent_id, :unless => -> { parent_id.nil? }
22 validates_presence_of :parent_id, :unless => -> { Node.root.nil? } 22 validates_presence_of :parent_id, :unless => -> { Node.root.nil? }
23 23
24 validate :borders # This should never ever happen.
25
26 # Index for Fulltext Search
27 # define_index do
28 # indexes head.translations.title
29 # indexes slug
30 # indexes unique_name
31 # indexes head.translations.body
32 # end
33
34 # Class methods 24 # Class methods
35 25
36 # Returns a page for a given node. If no revision is supplied, it returns 26 # Returns a page for a given node. If no revision is supplied, it returns
@@ -254,10 +244,13 @@ class Node < ApplicationRecord
254 # Watch out recursion ahead! update_unique_name itself triggers this 244 # Watch out recursion ahead! update_unique_name itself triggers this
255 # after_save callback which invokes update_unique_name on its children. 245 # after_save callback which invokes update_unique_name on its children.
256 # Hopefully until no childrens occur 246 # Hopefully until no childrens occur
247 #
248 # Queries parent_id directly rather than the NestedTree#children
249 # association out of habit from the old awesome_nested_set-avoidance
250 # workaround - no longer strictly necessary now that children is
251 # equally safe, but left as-is since it already works correctly.
257 def update_unique_names_of_children 252 def update_unique_names_of_children
258 unless root? 253 unless root?
259 # Use parent_id-based traversal instead of lft/rgt descendants
260 # due to awesome_nested_set not refreshing parent lft/rgt in memory
261 Node.where(:parent_id => self.id).each do |child| 254 Node.where(:parent_id => self.id).each do |child|
262 child.reload 255 child.reload
263 child.update_unique_name 256 child.update_unique_name
@@ -265,10 +258,4 @@ class Node < ApplicationRecord
265 end 258 end
266 end 259 end
267 end 260 end
268
269 def borders
270 if lft && rgt && (lft > rgt)
271 errors.add("Fuck!. lft should never be smaller than rgt")
272 end
273 end
274end 261end
diff --git a/db/seeds/chapters.rb b/db/seeds/chapters.rb
index bebc8da..4d81e3c 100644
--- a/db/seeds/chapters.rb
+++ b/db/seeds/chapters.rb
@@ -1409,6 +1409,3 @@ puts "Nodes flagged for review:"
1409(erfas + chaostreffs).select { |e| e[:review] }.each do |e| 1409(erfas + chaostreffs).select { |e| e[:review] }.each do |e|
1410 puts " #{e[:slug]}" 1410 puts " #{e[:slug]}"
1411end 1411end
1412
1413Node.rebuild!(false)
1414