Skip to content

Commit affda6f

Browse files
authored
Merge pull request #2026 from codidact/cellio/2025-prevent-tag-patricide
2 parents 315cb36 + cb3ae58 commit affda6f

2 files changed

Lines changed: 31 additions & 20 deletions

File tree

app/controllers/tags_controller.rb

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -225,30 +225,34 @@ def merge
225225
end
226226

227227
def nuke
228-
Post.transaction do
229-
AuditLog.admin_audit event_type: 'tag_nuke', related: @tag, user: current_user,
230-
comment: "#{@tag.name} (#{@tag.id})"
231-
232-
tables = ['posts_tags', 'categories_moderator_tags', 'categories_required_tags', 'categories_topic_tags',
233-
'post_history_tags', 'suggested_edits_tags', 'suggested_edits_before_tags']
234-
235-
# Remove tag from caches
236-
caches_sql = 'UPDATE posts INNER JOIN posts_tags ON posts.id = posts_tags.post_id ' \
237-
'SET posts.tags_cache = REPLACE(posts.tags_cache, ?, ?) ' \
238-
'WHERE posts_tags.tag_id = ?'
239-
exec_sql([caches_sql, "\n- #{@tag.name}\n", "\n", @tag.id])
228+
if @tag.children.any?
229+
flash[:error] = 'Cannot delete a tag that has children.'
230+
else
231+
Post.transaction do
232+
AuditLog.admin_audit event_type: 'tag_nuke', related: @tag, user: current_user,
233+
comment: "#{@tag.name} (#{@tag.id})"
234+
235+
tables = ['posts_tags', 'categories_moderator_tags', 'categories_required_tags', 'categories_topic_tags',
236+
'post_history_tags', 'suggested_edits_tags', 'suggested_edits_before_tags']
237+
238+
# Remove tag from caches
239+
caches_sql = 'UPDATE posts INNER JOIN posts_tags ON posts.id = posts_tags.post_id ' \
240+
'SET posts.tags_cache = REPLACE(posts.tags_cache, ?, ?) ' \
241+
'WHERE posts_tags.tag_id = ?'
242+
exec_sql([caches_sql, "\n- #{@tag.name}\n", "\n", @tag.id])
243+
244+
# Delete all references to the tag
245+
tables.each do |tbl|
246+
sql = "DELETE FROM #{tbl} WHERE tag_id = ?"
247+
exec_sql([sql, @tag.id])
248+
end
240249

241-
# Delete all references to the tag
242-
tables.each do |tbl|
243-
sql = "DELETE FROM #{tbl} WHERE tag_id = ?"
244-
exec_sql([sql, @tag.id])
250+
# Nuke it
251+
@tag.destroy
245252
end
246253

247-
# Nuke it
248-
@tag.destroy
254+
flash[:success] = "Deleted #{@tag.name}"
249255
end
250-
251-
flash[:success] = "Deleted #{@tag.name}"
252256
redirect_to category_tags_path(@category)
253257
end
254258

app/views/tags/nuke_warning.html.erb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66

77
<h1>Delete tag <%= @tag.name %></h1>
88

9+
<% if @tag.children.any? %>
10+
<div class="notice is-warning has-color-yellow-900">
11+
<p>Tags with children cannot be deleted. Please reparent the children first.</p>
12+
</div>
13+
<% else %>
14+
915
<div class="notice is-danger has-color-red-900">
1016
<p>
1117
Deleting a tag results in making it seem to have never existed in the first place. No record will be kept of the tag.
@@ -27,3 +33,4 @@
2733
role: 'button' do %>
2834
I understand, delete <%= @tag.name %>
2935
<% end %>
36+
<% end %>

0 commit comments

Comments
 (0)