DEV: Fix incorrect SyncTimerableIdTopicId migration (#34837)

Follow-up to eeeb7d302f

When `timerable_id` is `null`, `timerable_id != topic_id` will evaluate
to `null` so the row isn't updated.
This commit is contained in:
Alan Guo Xiang Tan
2025-09-17 13:54:29 +08:00
committed by GitHub
parent eeeb7d302f
commit 04dd93fe2c
2 changed files with 41 additions and 1 deletions
@@ -1,4 +1,5 @@
# frozen_string_literal: true
class SyncTimerableIdTopicId < ActiveRecord::Migration[8.0]
disable_ddl_transaction!
@@ -9,7 +10,7 @@ class SyncTimerableIdTopicId < ActiveRecord::Migration[8.0]
(min_id..max_id).step(batch_size) { |start_id| execute <<~SQL.squish } if min_id && max_id
UPDATE topic_timers
SET timerable_id = topic_id
WHERE id >= #{start_id} AND id < #{start_id + batch_size} AND timerable_id != topic_id
WHERE id >= #{start_id} AND id < #{start_id + batch_size} AND (timerable_id IS NULL OR timerable_id <> topic_id)
SQL
end
@@ -0,0 +1,39 @@
# frozen_string_literal: true
require Rails.root.join("db/migrate/20250902072941_sync_timerable_id_topic_id.rb")
RSpec.describe SyncTimerableIdTopicId do
before do
@original_verbose = ActiveRecord::Migration.verbose
ActiveRecord::Migration.verbose = false
end
after { ActiveRecord::Migration.verbose = @original_verbose }
it "works" do
DB.exec("DROP TRIGGER IF EXISTS topic_timers_topic_id_trigger ON topic_timers")
Migration::ColumnDropper.drop_readonly(:topic_timers, :topic_id)
DB.exec("ALTER TABLE topic_timers ALTER COLUMN timerable_id DROP NOT NULL")
DB.exec(
"INSERT INTO topic_timers (execute_at, status_type, type, created_at, updated_at, user_id, topic_id)
VALUES (NOW() + INTERVAL '60 minutes', 0, 'TopicTimer', NOW(), NOW(), 1, 12345)",
)
# Insert with id `20000` to ensure batching works as expected.
DB.exec(
"INSERT INTO topic_timers (id, execute_at, status_type, type, created_at, updated_at, user_id, topic_id)
VALUES (20000, NOW() + INTERVAL '60 minutes', 0, 'TopicTimer', NOW(), NOW(), 1, 67890)",
)
SyncTimerableIdTopicId.new.up
row = DB.query("SELECT * FROM topic_timers WHERE topic_id = 12345")[0]
expect(row.timerable_id).to eq(12_345)
row = DB.query("SELECT * FROM topic_timers WHERE topic_id = 67890")[0]
expect(row.timerable_id).to eq(67_890)
end
end