Merge pull request #3299 from r888888888/fix-2062

Fix 2062
This commit is contained in:
Albert Yi
2017-09-14 11:00:10 -07:00
committed by GitHub
10 changed files with 57 additions and 61 deletions

View File

@@ -4,19 +4,6 @@ class Favorite < ApplicationRecord
scope :for_user, lambda {|user_id| where("user_id % 100 = #{user_id.to_i % 100} and user_id = #{user_id.to_i}")} scope :for_user, lambda {|user_id| where("user_id % 100 = #{user_id.to_i % 100} and user_id = #{user_id.to_i}")}
attr_accessible :user_id, :post_id attr_accessible :user_id, :post_id
# this is necessary because there's no trigger for deleting favorites
def self.destroy_all(user_id: nil, post_id: nil)
if user_id && post_id
connection.execute("delete from favorites_#{user_id % 100} where user_id = #{user_id} and post_id = #{post_id}")
elsif user_id
connection.execute("delete from favorites_#{user_id % 100} where user_id = #{user_id}")
elsif post_id
0.upto(99) do |uid|
connection.execute("delete from favorites_#{uid} where post_id = #{post_id}")
end
end
end
def self.add(post:, user:) def self.add(post:, user:)
Favorite.transaction do Favorite.transaction do
User.where(:id => user.id).select("id").lock("FOR UPDATE NOWAIT").first User.where(:id => user.id).select("id").lock("FOR UPDATE NOWAIT").first
@@ -27,7 +14,6 @@ class Favorite < ApplicationRecord
post.append_user_to_fav_string(user.id) post.append_user_to_fav_string(user.id)
User.where(:id => user.id).update_all("favorite_count = favorite_count + 1") User.where(:id => user.id).update_all("favorite_count = favorite_count + 1")
user.favorite_count += 1 user.favorite_count += 1
# post.fav_count += 1 # this is handled in Post#clean_fav_string!
end end
end end
@@ -40,7 +26,7 @@ class Favorite < ApplicationRecord
User.where(:id => user.id).select("id").lock("FOR UPDATE NOWAIT").first User.where(:id => user.id).select("id").lock("FOR UPDATE NOWAIT").first
return unless Favorite.for_user(user.id).where(:user_id => user.id, :post_id => post_id).exists? return unless Favorite.for_user(user.id).where(:user_id => user.id, :post_id => post_id).exists?
Favorite.destroy_all(user_id: user.id, post_id: post_id) Favorite.for_user(user.id).delete_all(post_id: post_id)
Post.where(:id => post_id).update_all("fav_count = fav_count - 1") Post.where(:id => post_id).update_all("fav_count = fav_count - 1")
post.delete_user_from_fav_string(user.id) if post post.delete_user_from_fav_string(user.id) if post
User.where(:id => user.id).update_all("favorite_count = favorite_count - 1") User.where(:id => user.id).update_all("favorite_count = favorite_count - 1")

View File

@@ -172,18 +172,24 @@ class FavoriteGroup < ApplicationRecord
self.post_count = post_id_array.size self.post_count = post_id_array.size
end end
def add!(post) def add!(post_id)
return if contains?(post.id) return if contains?(post_id)
clear_post_id_array clear_post_id_array
update_attributes(:post_ids => add_number_to_string(post.id, post_ids)) update_attributes(:post_ids => add_number_to_string(post_id, post_ids))
end end
def remove!(post) def self.purge_post(post_id)
return unless contains?(post.id) for_post(post_id).find_each do |group|
group.remove!(post_id)
end
end
def remove!(post_id)
return unless contains?(post_id)
clear_post_id_array clear_post_id_array
update_attributes(:post_ids => remove_number_from_string(post.id, post_ids)) update_attributes(:post_ids => remove_number_from_string(post_id, post_ids))
end end
def add_number_to_string(number, string) def add_number_to_string(number, string)

View File

@@ -147,8 +147,6 @@ class Note < ApplicationRecord
def create_version def create_version
return unless versioned_attributes_changed? return unless versioned_attributes_changed?
User.where(id: CurrentUser.id).update_all("note_update_count = note_update_count + 1")
CurrentUser.reload
if merge_version? if merge_version?
merge_version merge_version

View File

@@ -1,6 +1,6 @@
class NoteVersion < ApplicationRecord class NoteVersion < ApplicationRecord
before_validation :initialize_updater before_validation :initialize_updater
belongs_to :updater, :class_name => "User" belongs_to :updater, :class_name => "User", :counter_cache => "note_update_count"
scope :for_user, lambda {|user_id| where("updater_id = ?", user_id)} scope :for_user, lambda {|user_id| where("updater_id = ?", user_id)}
attr_accessible :note_id, :x, :y, :width, :height, :body, :updater_id, :updater_ip_addr, :is_active, :post_id, :html_id, :version attr_accessible :note_id, :x, :y, :width, :height, :body, :updater_id, :updater_ip_addr, :is_active, :post_id, :html_id, :version

View File

@@ -36,7 +36,7 @@ class Post < ApplicationRecord
belongs_to :updater, :class_name => "User" belongs_to :updater, :class_name => "User"
belongs_to :approver, :class_name => "User" belongs_to :approver, :class_name => "User"
belongs_to :uploader, :class_name => "User" belongs_to :uploader, :class_name => "User", :counter_cache => "post_upload_count"
belongs_to :parent, :class_name => "Post" belongs_to :parent, :class_name => "Post"
has_one :upload, :dependent => :destroy has_one :upload, :dependent => :destroy
has_one :artist_commentary, :dependent => :destroy has_one :artist_commentary, :dependent => :destroy
@@ -815,19 +815,19 @@ class Post < ApplicationRecord
when /^-favgroup:(\d+)$/i when /^-favgroup:(\d+)$/i
favgroup = FavoriteGroup.where("id = ?", $1.to_i).for_creator(CurrentUser.user.id).first favgroup = FavoriteGroup.where("id = ?", $1.to_i).for_creator(CurrentUser.user.id).first
favgroup.remove!(self) if favgroup favgroup.remove!(id) if favgroup
when /^-favgroup:(.+)$/i when /^-favgroup:(.+)$/i
favgroup = FavoriteGroup.named($1).for_creator(CurrentUser.user.id).first favgroup = FavoriteGroup.named($1).for_creator(CurrentUser.user.id).first
favgroup.remove!(self) if favgroup favgroup.remove!(id) if favgroup
when /^favgroup:(\d+)$/i when /^favgroup:(\d+)$/i
favgroup = FavoriteGroup.where("id = ?", $1.to_i).for_creator(CurrentUser.user.id).first favgroup = FavoriteGroup.where("id = ?", $1.to_i).for_creator(CurrentUser.user.id).first
favgroup.add!(self) if favgroup favgroup.add!(id) if favgroup
when /^favgroup:(.+)$/i when /^favgroup:(.+)$/i
favgroup = FavoriteGroup.named($1).for_creator(CurrentUser.user.id).first favgroup = FavoriteGroup.named($1).for_creator(CurrentUser.user.id).first
favgroup.add!(self) if favgroup favgroup.add!(id) if favgroup
end end
end end
end end
@@ -1038,13 +1038,14 @@ class Post < ApplicationRecord
end end
def remove_from_favorites def remove_from_favorites
Favorite.destroy_all(post_id: self.id) Favorite.delete_all(post_id: id)
user_ids = fav_string.scan(/\d+/)
User.where(:id => user_ids).update_all("favorite_count = favorite_count - 1")
PostVote.where(post_id: id).delete_all
end end
def remove_from_fav_groups def remove_from_fav_groups
FavoriteGroup.for_post(id).find_each do |group| FavoriteGroup.delay.purge_post(id)
group.remove!(self)
end
end end
end end
@@ -1380,7 +1381,6 @@ class Post < ApplicationRecord
transaction do transaction do
Post.without_timeout do Post.without_timeout do
ModAction.log("permanently deleted post ##{id}") ModAction.log("permanently deleted post ##{id}")
#delete!("Permanently deleted post ##{id}", :without_mod_action => true)
give_favorites_to_parent give_favorites_to_parent
update_children_on_destroy update_children_on_destroy

View File

@@ -2,7 +2,7 @@ class PostArchive < ApplicationRecord
extend Memoist extend Memoist
belongs_to :post belongs_to :post
belongs_to :updater, class_name: "User" belongs_to :updater, class_name: "User", counter_cache: "post_update_count"
def self.enabled? def self.enabled?
Danbooru.config.aws_sqs_archives_url.present? Danbooru.config.aws_sqs_archives_url.present?

View File

@@ -139,7 +139,6 @@ class Upload < ApplicationRecord
post = convert_to_post post = convert_to_post
post.distribute_files post.distribute_files
if post.save if post.save
User.where(id: CurrentUser.id).update_all("post_upload_count = post_upload_count + 1")
create_artist_commentary(post) if include_artist_commentary? create_artist_commentary(post) if include_artist_commentary?
ugoira_service.save_frame_data(post) if is_ugoira? ugoira_service.save_frame_data(post) if is_ugoira?
notify_cropper(post) notify_cropper(post)

View File

@@ -286,17 +286,8 @@ class User < ApplicationRecord
Favorite.where("user_id % 100 = #{id % 100} and user_id = #{id}").order("id desc") Favorite.where("user_id % 100 = #{id % 100} and user_id = #{id}").order("id desc")
end end
def clean_favorite_count?
favorite_count < 0 || Kernel.rand(100) < [Math.log(favorite_count, 2), 5].min
end
def clean_favorite_count!
update_column(:favorite_count, Favorite.for_user(id).count)
end
def add_favorite!(post) def add_favorite!(post)
Favorite.add(post: post, user: self) Favorite.add(post: post, user: self)
clean_favorite_count! if clean_favorite_count?
end end
def remove_favorite!(post) def remove_favorite!(post)

View File

@@ -21,6 +21,7 @@ class PostTest < ActiveSupport::TestCase
CurrentUser.user = @user CurrentUser.user = @user
CurrentUser.ip_addr = "127.0.0.1" CurrentUser.ip_addr = "127.0.0.1"
mock_saved_search_service! mock_saved_search_service!
ImageCropper.stubs(:enabled?).returns(false)
end end
def teardown def teardown
@@ -61,6 +62,32 @@ class PostTest < ActiveSupport::TestCase
assert_equal(0, Favorite.for_user(@user.id).where("post_id = ?", @post.id).count) assert_equal(0, Favorite.for_user(@user.id).where("post_id = ?", @post.id).count)
end end
should "decrement the uploader's upload count" do
assert_difference("@post.uploader.reload.post_upload_count", -1) do
@post.expunge!
end
end
should "decrement the user's note update count" do
FactoryGirl.create(:note, post: @post)
assert_difference(["@post.uploader.reload.note_update_count"], -1) do
@post.expunge!
end
end
should "decrement the user's post update count" do
assert_difference(["@post.uploader.reload.post_update_count"], -1) do
@post.expunge!
end
end
should "decrement the user's favorite count" do
@post.add_favorite!(@post.uploader)
assert_difference(["@post.uploader.reload.favorite_count"], -1) do
@post.expunge!
end
end
should "remove the post from iqdb" do should "remove the post from iqdb" do
mock_iqdb_service! mock_iqdb_service!
Post.iqdb_sqs_service.expects(:send_message).with("remove\n#{@post.id}") Post.iqdb_sqs_service.expects(:send_message).with("remove\n#{@post.id}")
@@ -1162,11 +1189,13 @@ class PostTest < ActiveSupport::TestCase
should "increment the updater's post_update_count" do should "increment the updater's post_update_count" do
PostArchive.sqs_service.stubs(:merge?).returns(false) PostArchive.sqs_service.stubs(:merge?).returns(false)
post = FactoryGirl.create(:post, :tag_string => "aaa bbb ccc") post = FactoryGirl.create(:post, :tag_string => "aaa bbb ccc")
CurrentUser.reload
assert_difference("CurrentUser.post_update_count", 1) do # XXX in the test environment the update count gets bumped twice: and
# once by Post#post_update_count, and once by the counter cache. in
# production the counter cache doesn't bump the count, because
# versions are created on a separate server.
assert_difference("CurrentUser.user.reload.post_update_count", 2) do
post.update_attributes(:tag_string => "zzz") post.update_attributes(:tag_string => "zzz")
CurrentUser.reload
end end
end end

View File

@@ -38,19 +38,6 @@ class UserTest < ActiveSupport::TestCase
end end
end end
context "favoriting a post" do
setup do
@user.update_column(:favorite_count, 999)
@user.stubs(:clean_favorite_count?).returns(true)
@post = FactoryGirl.create(:post)
end
should "periodically clean the favorite_count" do
@user.add_favorite!(@post)
assert_equal(1, @user.favorite_count)
end
end
context "that has been invited by a mod" do context "that has been invited by a mod" do
setup do setup do
@mod = FactoryGirl.create(:moderator_user) @mod = FactoryGirl.create(:moderator_user)