From e53d71b31b02d925114f5b96c845f90d608482a9 Mon Sep 17 00:00:00 2001 From: albert Date: Tue, 5 Mar 2013 22:51:21 -0500 Subject: [PATCH] fixes #749, fixes tag alias related regressions --- app/logical/tag_alias_correction.rb | 5 +- app/models/tag.rb | 74 ++++++++++++-------------- app/models/tag_alias.rb | 19 ++++++- test/unit/tag_alias_correction_test.rb | 3 +- test/unit/tag_alias_test.rb | 8 +++ 5 files changed, 64 insertions(+), 45 deletions(-) diff --git a/app/logical/tag_alias_correction.rb b/app/logical/tag_alias_correction.rb index 3316c5ea5..971ca076d 100644 --- a/app/logical/tag_alias_correction.rb +++ b/app/logical/tag_alias_correction.rb @@ -51,9 +51,8 @@ class TagAliasCorrection def fix! clear_cache - Post.raw_tag_match(tag_alias.antecedent_name).each do |post| - post.save - end + tag_alias.update_cache + tag_alias.update_posts tag_alias.antecedent_tag.fix_post_count if tag_alias.antecedent_tag tag_alias.consequent_tag.fix_post_count if tag_alias.consequent_tag end diff --git a/app/models/tag.rb b/app/models/tag.rb index b33c2f48a..917f339c4 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -34,6 +34,8 @@ class Tag < ActiveRecord::Base end module CountMethods + extend ActiveSupport::Concern + module ClassMethods def counts_for(tag_names) select_all_sql("SELECT name, post_count FROM tags WHERE name IN (?)", tag_names) @@ -102,45 +104,39 @@ class Tag < ActiveRecord::Base end module NameMethods - module ClassMethods - def normalize_name(name) - name.downcase.tr(" ", "_").gsub(/\A[-~]+/, "").gsub(/\*/, "") - end - - def find_or_create_by_name(name, options = {}) - name = normalize_name(name) - category = nil - - if name =~ /\A(#{categories.regexp}):(.+)\Z/ - category = $1 - name = $2 - end - - tag = find_by_name(name) - - if tag - if category - category_id = categories.value_for(category) - - if category_id != tag.category - tag.update_column(:category, category_id) - tag.update_category_cache_for_all - end - end - - tag - else - Tag.new.tap do |t| - t.name = name - t.category = categories.value_for(category) - t.save - end - end - end + def normalize_name(name) + name.downcase.tr(" ", "_").gsub(/\A[-~]+/, "").gsub(/\*/, "") end - - def self.included(m) - m.extend(ClassMethods) + + def find_or_create_by_name(name, options = {}) + name = normalize_name(name) + category = nil + + if name =~ /\A(#{categories.regexp}):(.+)\Z/ + category = $1 + name = $2 + end + + tag = find_by_name(name) + + if tag + if category + category_id = categories.value_for(category) + + if category_id != tag.category + tag.update_column(:category, category_id) + tag.update_category_cache_for_all + end + end + + tag + else + Tag.new.tap do |t| + t.name = name + t.category = categories.value_for(category) + t.save + end + end end end @@ -468,7 +464,7 @@ class Tag < ActiveRecord::Base extend ViewCountMethods include CategoryMethods extend StatisticsMethods - include NameMethods + extend NameMethods extend ParseMethods include RelationMethods extend SuggestionMethods diff --git a/app/models/tag_alias.rb b/app/models/tag_alias.rb index 968cde74f..7a1023413 100644 --- a/app/models/tag_alias.rb +++ b/app/models/tag_alias.rb @@ -1,6 +1,7 @@ class TagAlias < ActiveRecord::Base after_save :clear_all_cache after_save :update_cache + after_save :ensure_category_consistency after_destroy :clear_all_cache before_validation :initialize_creator, :on => :create validates_presence_of :creator_id @@ -86,6 +87,14 @@ class TagAlias < ActiveRecord::Base end end + def ensure_category_consistency + if antecedent_tag && consequent_tag && antecedent_tag.category != consequent_tag.category + consequent_tag.update_attribute(:category, antecedent_tag.category) + end + + true + end + def clear_all_cache Danbooru.config.all_server_hosts.each do |host| delay(:queue => host).clear_cache(host) @@ -103,8 +112,14 @@ class TagAlias < ActiveRecord::Base end def update_posts - Post.raw_tag_match(antecedent_name).each do |post| - post.save + Post.raw_tag_match(antecedent_name).find_each do |post| + escaped_antecedent_name = Regexp.escape(antecedent_name) + fixed_tags = post.tag_string.sub(/(?:\A| )#{escaped_antecedent_name}(?:\Z| )/, " #{consequent_name} ").strip + CurrentUser.scoped(creator, creator_ip_addr) do + post.update_attributes( + :tag_string => fixed_tags + ) + end end end end diff --git a/test/unit/tag_alias_correction_test.rb b/test/unit/tag_alias_correction_test.rb index 1fec55e2e..2790f7824 100644 --- a/test/unit/tag_alias_correction_test.rb +++ b/test/unit/tag_alias_correction_test.rb @@ -13,6 +13,7 @@ class TagAliasTest < ActiveSupport::TestCase end teardown do + MEMCACHE.flush_all CurrentUser.user = nil CurrentUser.ip_addr = nil end @@ -28,7 +29,7 @@ class TagAliasTest < ActiveSupport::TestCase assert_equal("zzz", @correction.statistics_hash["antecedent_cache"]) assert_nil(@correction.statistics_hash["consequent_cache"]) assert_equal(-3, @correction.statistics_hash["antecedent_count"]) - assert_nil(@correction.statistics_hash["consequent_count"]) + assert_equal(1, @correction.statistics_hash["consequent_count"]) end should "render to json" do diff --git a/test/unit/tag_alias_test.rb b/test/unit/tag_alias_test.rb index 2747dad98..d58ba8506 100644 --- a/test/unit/tag_alias_test.rb +++ b/test/unit/tag_alias_test.rb @@ -73,5 +73,13 @@ class TagAliasTest < ActiveSupport::TestCase assert_not_equal(tag_alias.creator_id, post.uploader_id) assert_equal(tag_alias.creator_id, post.versions.last.updater_id) end + + should "push the antecedent's category to the consequent" do + tag1 = FactoryGirl.create(:tag, :name => "aaa", :category => 1) + tag2 = FactoryGirl.create(:tag, :name => "bbb") + ta = FactoryGirl.create(:tag_alias, :antecedent_name => "aaa", :consequent_name => "bbb") + tag2.reload + assert_equal(1, tag2.category) + end end end