Introduce a recurring job to delete unused tags

ref: https://37s.fizzy.37signals.com/collections/693169850/cards/999009072
This commit is contained in:
Mike Dalessio (aider)
2025-05-14 11:46:47 -04:00
committed by Mike Dalessio
parent 95f0f10f2f
commit 2f9a0bbe75
5 changed files with 40 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
class DeleteUnusedTagsJob < ApplicationJob
def perform
ApplicationRecord.with_each_tenant do |tenant|
Tag.unused.find_each do |tag|
tag.destroy!
end
end
end
end
+1
View File
@@ -8,6 +8,7 @@ class Tag < ApplicationRecord
normalizes :title, with: -> { it.downcase }
scope :alphabetically, -> { order("lower(title)") }
scope :unused, -> { left_outer_joins(:taggings).where(taggings: { id: nil }) }
def hashtag
"#" + title
+3
View File
@@ -11,3 +11,6 @@ production:
sqlite_backups:
class: SQLiteBackupsJob
schedule: every day at 05:00
delete_unused_tags:
class: DeleteUnusedTagsJob
schedule: every day at 04:00
+13
View File
@@ -0,0 +1,13 @@
require "test_helper"
class DeleteUnusedTagsJobTest < ActiveJob::TestCase
test "deletes tags that are not used by any cards" do
unused = Tag.create!(title: "unused")
assert_changes -> { Tag.count }, -1 do
DeleteUnusedTagsJob.perform_now
end
assert_not Tag.exists?(unused.id), "Unused tag should be deleted"
end
end
+14
View File
@@ -4,4 +4,18 @@ class TagTest < ActiveSupport::TestCase
test "downcase title" do
assert_equal "a tag", Tag.create!(title: "A TAG").title
end
test ".unused returns tags not associated with any cards" do
unused = Tag.create!(title: "unused")
unused_tags = Tag.unused
assert_includes unused_tags, unused
assert_not_includes unused_tags, tags(:web)
assert_not_includes unused_tags, tags(:mobile)
end
test ".unused returns empty relation if all tags are used" do
assert_empty Tag.unused
end
end