diff --git a/app/models/common_tagging.rb b/app/models/common_tagging.rb index 3e826c9a55c..333b5e9196d 100644 --- a/app/models/common_tagging.rb +++ b/app/models/common_tagging.rb @@ -23,6 +23,8 @@ class CommonTagging < ApplicationRecord after_commit :update_search + before_destroy :remove_from_autocomplete + def update_wrangler unless User.current_user.nil? common_tag.update!(last_wrangler: User.current_user) @@ -33,6 +35,10 @@ def add_to_autocomplete common_tag.add_to_fandom_autocomplete(filterable) end + def remove_from_autocomplete + common_tag&.remove_from_fandom_autocomplete(filterable) + end + # A relationship should inherit its characters' fandoms def inherit_parents if common_tag.is_a?(Relationship) && filterable.is_a?(Character) diff --git a/app/models/tag.rb b/app/models/tag.rb index f6fd5fd21ef..6b5c6cda0e5 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -488,13 +488,18 @@ def add_to_fandom_autocomplete(fandom, score = nil) def remove_from_autocomplete super - if self.is_a?(Character) || self.is_a?(Relationship) - parents.each do |parent| - REDIS_AUTOCOMPLETE.zrem(self.transliterate("autocomplete_fandom_#{parent.name.downcase}_#{type.downcase}"), autocomplete_value) if parent.is_a?(Fandom) - end + parents.each do |parent| + remove_from_fandom_autocomplete(parent) end end + def remove_from_fandom_autocomplete(fandom) + return unless fandom.is_a?(Fandom) + return unless self.is_a?(Character) || self.is_a?(Relationship) + + REDIS_AUTOCOMPLETE.zrem(self.transliterate("autocomplete_fandom_#{fandom.name.downcase}_#{type.downcase}"), autocomplete_value) + end + def remove_stale_from_autocomplete super if self.is_a?(Character) || self.is_a?(Relationship) diff --git a/spec/models/tag_wrangling_spec.rb b/spec/models/tag_wrangling_spec.rb index fb4284724a2..1f920d657cb 100644 --- a/spec/models/tag_wrangling_spec.rb +++ b/spec/models/tag_wrangling_spec.rb @@ -193,9 +193,7 @@ synonym.add_association(child) synonym.reload - fandom_redis_key = Tag.transliterate("autocomplete_fandom_#{fandom.name.downcase}_character") - - expect(REDIS_AUTOCOMPLETE.exists(fandom_redis_key)).to be false + expect_autocomplete_to_return(fandom, []) synonym.update!(syn_string: fandom.name) @@ -205,8 +203,7 @@ expect(fandom.children.reload).to contain_exactly(child) expect(synonym.children.reload).to be_empty - expect(REDIS_AUTOCOMPLETE.exists(fandom_redis_key)).to be true - expect(REDIS_AUTOCOMPLETE.zrange(fandom_redis_key, 0, -1)).to eq(["#{child.id}: #{child.name}"]) + expect_autocomplete_to_return(fandom, [child]) end end @@ -577,4 +574,39 @@ expect(work.filters.reload).not_to include(meta) end end + + describe "associations" do + it "updates Redis autocomplete when adding a canon character to a canon fandom" do + fandom = create(:canonical_fandom) + character = create(:canonical_character) + + expect_autocomplete_to_return(fandom, []) + + fandom.add_association(character) + expect_autocomplete_to_return(fandom, [character]) + end + + it "updates Redis autocomplete when removing a canon character from a fandom" do + fandom = create(:canonical_fandom) + character = create(:canonical_character) + + fandom.add_association(character) + expect_autocomplete_to_return(fandom, [character]) + + fandom.child_taggings.destroy_all + expect_autocomplete_to_return(fandom, []) + end + end + + def redis_autocomplete_key(fandom) + Tag.transliterate("autocomplete_fandom_#{fandom.name.downcase}_character") + end + + def redis_autocomplete_store(fandom) + REDIS_AUTOCOMPLETE.zrange(redis_autocomplete_key(fandom), 0, -1) + end + + def expect_autocomplete_to_return(fandom, characters) + expect(redis_autocomplete_store(fandom)).to eq characters.map { |character| "#{character.id}: #{character.name}" } + end end