Remove reactions to a user when deleting the user (#15724)
* Remove reactions to a user when deleting the user Fixes #15245 --- I have no idea why `create(:vomit_reaction, reactable: user)` gave a validation error about category being invalid, but `build().save` worked fine. * Move relation details to reaction scope `for_user` Add a user method to access this by passing self to reaction scope * Create a moderator when flagging user in factory This might be a missing requirement in the reactions factory - but this suppresses an error about invalid category I was getting when setting a privileged reaction on the user via create(:vomit_reaction, reactable: user) Everywhere else it looks like we do this with `user: moderator` (where there's a trusted user in the surrounding context). * Move trusted user requirement into vomit_reaction factory * Add a data update script to remove reactions to deleted users This cleans up the remaining invalid references and should make the change in #15249 obsolete (i.e. we don't need to limit the view to exclude items that no longer exist).
This commit is contained in:
parent
428dd1bd2c
commit
421dad2900
7 changed files with 45 additions and 1 deletions
|
|
@ -42,6 +42,7 @@ class Reaction < ApplicationRecord
|
|||
.or(user_vomits.where(user_id: user.id))
|
||||
}
|
||||
scope :privileged_category, -> { where(category: PRIVILEGED_CATEGORIES) }
|
||||
scope :for_user, ->(user) { where(reactable: user) }
|
||||
|
||||
validates :category, inclusion: { in: CATEGORIES }
|
||||
validates :reactable_type, inclusion: { in: REACTABLE_TYPES }
|
||||
|
|
|
|||
|
|
@ -536,6 +536,10 @@ class User < ApplicationRecord
|
|||
notification_setting.email_follower_notifications
|
||||
end
|
||||
|
||||
def reactions_to
|
||||
Reaction.for_user(self)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Send emails asynchronously
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ module Users
|
|||
def delete_profile_info(user)
|
||||
user.notifications.delete_all
|
||||
user.reactions.delete_all
|
||||
user.reactions_to.delete_all
|
||||
user.follows.delete_all
|
||||
Follow.followable_user(user.id).delete_all
|
||||
user.mentions.delete_all
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
module DataUpdateScripts
|
||||
class RemoveDanglingUserReactions
|
||||
def run
|
||||
# reactions to users who have been deleted should be removed:
|
||||
Reaction
|
||||
.where(reactable_type: "User")
|
||||
.where.not(reactable_id: User.all.select(:id))
|
||||
.delete_all
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -22,7 +22,7 @@ FactoryBot.define do
|
|||
end
|
||||
|
||||
factory :vomit_reaction, class: "Reaction" do
|
||||
user
|
||||
user { create(:user, :trusted) }
|
||||
association :reactable, factory: :article
|
||||
category { "vomit" }
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
require "rails_helper"
|
||||
require Rails.root.join(
|
||||
"lib/data_update_scripts/20211209213849_remove_dangling_user_reactions.rb",
|
||||
)
|
||||
|
||||
describe DataUpdateScripts::RemoveDanglingUserReactions do
|
||||
let(:user_to_delete) { create(:user) }
|
||||
|
||||
before do
|
||||
create(:vomit_reaction, reactable: user_to_delete)
|
||||
|
||||
# there's no dependent callback on reactions_to so the reaction is not removed
|
||||
user_to_delete.destroy
|
||||
end
|
||||
|
||||
it "removes reactions to deleted users" do
|
||||
expect { described_class.new.run }.to change(Reaction, :count).by(-1)
|
||||
end
|
||||
end
|
||||
|
|
@ -68,6 +68,14 @@ RSpec.describe Users::Delete, type: :service do
|
|||
end.to change(FieldTest::Membership, :count).by(-1)
|
||||
end
|
||||
|
||||
it "deletes reactions to the user" do
|
||||
create(:vomit_reaction, reactable: user)
|
||||
|
||||
expect do
|
||||
described_class.call(user)
|
||||
end.to change(Reaction, :count).by(-1)
|
||||
end
|
||||
|
||||
# check that all the associated records are being destroyed,
|
||||
# except for those that are kept explicitly (kept_associations)
|
||||
describe "deleting associations" do
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue