summaryrefslogtreecommitdiff
path: root/app/models/node.rb
diff options
context:
space:
mode:
authorerdgeist <erdgeist@erdgeist.org>2026-07-31 20:41:05 +0200
committererdgeist <erdgeist@erdgeist.org>2026-07-31 20:41:05 +0200
commit3b4e1423635fd9f33ae760312e438cc1e484662e (patch)
tree0dd81aaf26ab5e4d7e178563f120b3e203c4dc0b /app/models/node.rb
parent683526b38442a9873d83a542b5cba1d15efc14d5 (diff)
Show the gate before it refuses, and check the destination
nodes#show renders publish and trash as disabled_action spans with a hint naming what an editor can still do, matching how locked_by_other already reads. Editing and reverting stay live: drafting is free everywhere.
Diffstat (limited to 'app/models/node.rb')
-rw-r--r--app/models/node.rb23
1 files changed, 16 insertions, 7 deletions
diff --git a/app/models/node.rb b/app/models/node.rb
index ac3a6160..188b6c17 100644
--- a/app/models/node.rb
+++ b/app/models/node.rb
@@ -236,7 +236,7 @@ class Node < ApplicationRecord
236 # Return nil if nothing to publish and no staged changes 236 # Return nil if nothing to publish and no staged changes
237 return nil unless self.draft || staged_slug || staged_parent_id 237 return nil unless self.draft || staged_slug || staged_parent_id
238 238
239 guard_live_change!(current_user) 239 guard_live_change!(current_user, :target_path => prospective_unique_name)
240 240
241 if in_trash? || trash_node? 241 if in_trash? || trash_node?
242 errors.add(:base, :publish_in_trash) 242 errors.add(:base, :publish_in_trash)
@@ -574,10 +574,8 @@ class Node < ApplicationRecord
574 false 574 false
575 end 575 end
576 576
577 def restricted? 577 def self.restricted_path? name
578 return true if root? 578 name = name.to_s
579
580 name = unique_name.to_s
581 return false if name.empty? 579 return false if name.empty?
582 580
583 CccConventions::RESTRICTED_SUBTREES.any? do |prefix| 581 CccConventions::RESTRICTED_SUBTREES.any? do |prefix|
@@ -585,6 +583,17 @@ class Node < ApplicationRecord
585 end 583 end
586 end 584 end
587 585
586 def restricted?
587 root? || self.class.restricted_path?(unique_name)
588 end
589
590 def prospective_unique_name
591 target_parent = staged_parent_id ? Node.find_by(:id => staged_parent_id) : parent
592 return nil unless target_parent
593
594 [target_parent.unique_name.presence, staged_slug.presence || slug].compact.join("/")
595 end
596
588 # Returns immutable node id for all new nodes so that the atom feed entry ids 597 # Returns immutable node id for all new nodes so that the atom feed entry ids
589 # stay the same eventhough the slug or positions changes. 598 # stay the same eventhough the slug or positions changes.
590 # Can be removed after a year or so ;) 599 # Can be removed after a year or so ;)
@@ -697,9 +706,9 @@ class Node < ApplicationRecord
697 706
698 private 707 private
699 708
700 def guard_live_change! user 709 def guard_live_change! user, target_path: nil
701 return if user.nil? 710 return if user.nil?
702 return if user.may_change_live?(self) 711 return if user.may_change_live?(self) && user.may_change_live_at?(target_path)
703 712
704 errors.add(:base, :not_permitted) 713 errors.add(:base, :not_permitted)
705 raise ActiveRecord::RecordInvalid.new(self) 714 raise ActiveRecord::RecordInvalid.new(self)