diff options
| author | erdgeist <erdgeist@erdgeist.org> | 2026-07-12 14:26:30 +0200 |
|---|---|---|
| committer | erdgeist <erdgeist@erdgeist.org> | 2026-07-12 14:26:30 +0200 |
| commit | 5803c59192b7fb05840d0b452eb64d9f997f3d8f (patch) | |
| tree | 09ce87657484ce8508dd6fca12570c0d044f3819 /app | |
| parent | 19e0ee821d5b2b6d3397a81411f4f3a4cbd2fa83 (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.rb | 9 | ||||
| -rw-r--r-- | app/models/node.rb | 16 |
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 |
