summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorerdgeist <erdgeist@erdgeist.org>2026-07-12 14:26:30 +0200
committererdgeist <erdgeist@erdgeist.org>2026-07-12 14:26:30 +0200
commit5803c59192b7fb05840d0b452eb64d9f997f3d8f (patch)
tree09ce87657484ce8508dd6fca12570c0d044f3819 /app
parent19e0ee821d5b2b6d3397a81411f4f3a4cbd2fa83 (diff)
Extract drafts/recent query logic from controller into Node
Node.drafts_and_autosaves and Node.recently_changed replace inline query logic in NodesController#drafts/#recent -- pure refactor, no behavior change for either action. The real reason: the dashboard's upcoming abridged widgets need the exact same queries the full pages already use, just limited and (for drafts) sorted with the current user's own locked nodes first. Better to share one method than let a widget and a full page quietly drift onto two versions of "what counts as a current draft." current_user_id: is an explicit, optional argument rather than a separate method -- ordering by lock ownership only applies when a user is given; omitted entirely, it's pure recency, exactly today's behavior. Needed Arel.sql wrapping a sanitized CASE expression before .order would accept it -- sanitize_sql_array only vouches for the values inside the string, a separate Rails safety check still refuses any string shaped like more than a plain column reference unless it's explicitly marked as already-vetted.
Diffstat (limited to 'app')
-rw-r--r--app/controllers/nodes_controller.rb9
-rw-r--r--app/models/node.rb16
2 files changed, 18 insertions, 7 deletions
diff --git a/app/controllers/nodes_controller.rb b/app/controllers/nodes_controller.rb
index 772bf4b..c1468be 100644
--- a/app/controllers/nodes_controller.rb
+++ b/app/controllers/nodes_controller.rb
@@ -185,16 +185,11 @@ class NodesController < ApplicationController
185 185
186 # Filter functions for admin views 186 # Filter functions for admin views
187 def drafts 187 def drafts
188 base = Node.where("draft_id IS NOT NULL OR autosave_id IS NOT NULL") 188 @nodes = index_matching(Node.drafts_and_autosaves)
189 @nodes = index_matching(base)
190 end 189 end
191 190
192 def recent 191 def recent
193 base = Node.where( 192 @nodes = index_matching(Node.recently_changed)
194 "nodes.updated_at < ? AND nodes.updated_at > ? AND nodes.parent_id IS NOT NULL",
195 Time.now, Time.now - 14.days
196 )
197 @nodes = index_matching(base)
198 end 193 end
199 194
200 def mine 195 def mine
diff --git a/app/models/node.rb b/app/models/node.rb
index 24f3cd0..aa2f7f3 100644
--- a/app/models/node.rb
+++ b/app/models/node.rb
@@ -367,6 +367,22 @@ class Node < ApplicationRecord
367 .distinct 367 .distinct
368 end 368 end
369 369
370 def self.drafts_and_autosaves(current_user_id: nil)
371 scope = where("draft_id IS NOT NULL OR autosave_id IS NOT NULL")
372 return scope.order("updated_at DESC") unless current_user_id
373
374 scope.order(
375 Arel.sql(sanitize_sql_array(["CASE WHEN locking_user_id = ? THEN 0 ELSE 1 END, updated_at DESC", current_user_id]))
376 )
377 end
378
379 def self.recently_changed
380 where(
381 "nodes.updated_at < ? AND nodes.updated_at > ? AND nodes.parent_id IS NOT NULL",
382 Time.now, Time.now - 14.days
383 )
384 end
385
370 protected 386 protected
371 def lock_for! current_user 387 def lock_for! current_user
372 self.lock_owner = current_user 388 self.lock_owner = current_user