FIX: when uploads are destroyed clear up avatar refs in user table

This also auto corrects twice daily when we ensure consistency
This commit is contained in:
Sam 2018-08-31 14:46:22 +10:00
parent 6b9aeeea73
commit e1975e293f
6 changed files with 101 additions and 0 deletions

View File

@ -17,6 +17,8 @@ module Jobs
UserOption.ensure_consistency!
Tag.ensure_consistency!
CategoryTagStat.ensure_consistency!
User.ensure_consistency!
UserAvatar.ensure_consistency!
end
end
end

View File

@ -24,6 +24,12 @@ class Upload < ActiveRecord::Base
validates_with ::Validators::UploadValidator
after_destroy do
User.where(uploaded_avatar_id: self.id).update_all(uploaded_avatar_id: nil)
UserAvatar.where(gravatar_upload_id: self.id).update_all(gravatar_upload_id: nil)
UserAvatar.where(custom_upload_id: self.id).update_all(custom_upload_id: nil)
end
def thumbnail(width = self.thumbnail_width, height = self.thumbnail_height)
optimized_images.find_by(width: width, height: height)
end

View File

@ -1283,6 +1283,20 @@ class User < ActiveRecord::Base
true
end
def self.ensure_consistency!
DB.exec <<~SQL
UPDATE users
SET uploaded_avatar_id = NULL
WHERE uploaded_avatar_id IN (
SELECT u1.uploaded_avatar_id FROM users u1
LEFT JOIN uploads up
ON u1.uploaded_avatar_id = up.id
WHERE u1.uploaded_avatar_id IS NOT NULL AND
up.id IS NULL
)
SQL
end
end
# == Schema Information

View File

@ -123,6 +123,31 @@ class UserAvatar < ActiveRecord::Base
tempfile.close! if tempfile && tempfile.respond_to?(:close!)
end
def self.ensure_consistency!
DB.exec <<~SQL
UPDATE user_avatars
SET gravatar_upload_id = NULL
WHERE gravatar_upload_id IN (
SELECT u1.gravatar_upload_id FROM user_avatars u1
LEFT JOIN uploads up
ON u1.gravatar_upload_id = up.id
WHERE u1.gravatar_upload_id IS NOT NULL AND
up.id IS NULL
)
SQL
DB.exec <<~SQL
UPDATE user_avatars
SET custom_upload_id = NULL
WHERE custom_upload_id IN (
SELECT u1.custom_upload_id FROM user_avatars u1
LEFT JOIN uploads up
ON u1.custom_upload_id = up.id
WHERE u1.custom_upload_id IS NOT NULL AND
up.id IS NULL
)
SQL
end
end
# == Schema Information

View File

@ -118,4 +118,38 @@ describe UserAvatar do
end
end
end
describe "ensure_consistency!" do
it "will clean up dangling avatars" do
upload1 = Fabricate(:upload)
upload2 = Fabricate(:upload)
user_avatar = Fabricate(:user).user_avatar
user_avatar.update_columns(
gravatar_upload_id: upload1.id,
custom_upload_id: upload2.id
)
upload1.destroy!
upload2.destroy!
user_avatar.reload
expect(user_avatar.gravatar_upload_id).to eq(nil)
expect(user_avatar.custom_upload_id).to eq(nil)
user_avatar.update_columns(
gravatar_upload_id: upload1.id,
custom_upload_id: upload2.id
)
UserAvatar.ensure_consistency!
user_avatar.reload
expect(user_avatar.gravatar_upload_id).to eq(nil)
expect(user_avatar.custom_upload_id).to eq(nil)
end
end
end

View File

@ -1794,4 +1794,24 @@ describe User do
end
end
describe "ensure_consistency!" do
it "will clean up dangling avatars" do
upload = Fabricate(:upload)
user = Fabricate(:user, uploaded_avatar_id: upload.id)
upload.destroy!
user.reload
expect(user.uploaded_avatar_id).to eq(nil)
user.update_columns(uploaded_avatar_id: upload.id)
User.ensure_consistency!
user.reload
expect(user.uploaded_avatar_id).to eq(nil)
end
end
end