aliases/implications: remove 'pending' state.

Remove the pending status from tag aliases and implications.

Previously aliases would be created first in the pending state then
changed to active when the alias was later processed in a delayed job.
This meant that BURs weren't processed completely sequentially; first
all the aliases in a BUR would be created in one go, then later they
would be processed and set to active sequentially.

This was problematic in complex BURs that tried to reverse or swap
around aliases, since new pending aliases could be created before old
conflicting aliases were removed.
This commit is contained in:
evazion
2020-12-01 15:30:42 -06:00
parent 45d050d918
commit 8717c319ab
19 changed files with 70 additions and 114 deletions

View File

@@ -192,8 +192,7 @@ class Artist < ApplicationRecord
# potential race condition but unlikely
unless TagImplication.where(:antecedent_name => name, :consequent_name => "banned_artist").exists?
tag_implication = TagImplication.create!(antecedent_name: name, consequent_name: "banned_artist", creator: banner)
tag_implication.approve!(banner)
TagImplication.approve!(antecedent_name: name, consequent_name: "banned_artist", approver: banner)
end
update!(is_banned: true)

View File

@@ -3,10 +3,6 @@ class TagAlias < TagRelationship
validates_uniqueness_of :antecedent_name, scope: :status, conditions: -> { active }
validate :absence_of_transitive_relation
def approve!(approver)
ProcessTagAliasJob.perform_later(self, approver)
end
def self.to_aliased(names)
names = Array(names).map(&:to_s)
return [] if names.empty?
@@ -14,8 +10,7 @@ class TagAlias < TagRelationship
names.map { |name| aliases[name] || name }
end
def process!(approver)
update!(approver: approver, status: "active")
def process!
TagMover.new(antecedent_name, consequent_name, user: User.system).move!
rescue Exception => e
update!(status: "error: #{e}")

View File

@@ -109,13 +109,8 @@ class TagImplication < TagRelationship
end
module ApprovalMethods
def process!(approver)
unless valid?
raise errors.full_messages.join("; ")
end
def process!
CurrentUser.scoped(User.system) do
update!(approver: approver, status: "active")
update_posts
end
rescue Exception => e
@@ -123,10 +118,6 @@ class TagImplication < TagRelationship
DanbooruLogger.log(e, tag_implication_id: id, antecedent_name: antecedent_name, consequent_name: consequent_name)
end
def approve!(approver)
ProcessTagImplicationJob.perform_later(self, approver)
end
def create_mod_action
implication = %("tag implication ##{id}":[#{Rails.application.routes.url_helpers.tag_implication_path(self)}]: [[#{antecedent_name}]] -> [[#{consequent_name}]])

View File

@@ -17,11 +17,10 @@ class TagRelationship < ApplicationRecord
scope :deleted, -> {where(status: "deleted")}
scope :expired, -> {where("created_at < ?", EXPIRY.days.ago)}
scope :old, -> {where("created_at >= ? and created_at < ?", EXPIRY.days.ago, EXPIRY_WARNING.days.ago)}
scope :pending, -> {where(status: "pending")}
scope :retired, -> {where(status: "retired")}
before_validation :normalize_names
validates_format_of :status, :with => /\A(active|deleted|pending|retired|error: .*)\Z/
validates_format_of :status, :with => /\A(active|deleted|retired|error: .*)\Z/
validates_presence_of :antecedent_name, :consequent_name
validates :approver, presence: { message: "must exist" }, if: -> { approver_id.present? }
validates :forum_topic, presence: { message: "must exist" }, if: -> { forum_topic_id.present? }
@@ -44,10 +43,6 @@ class TagRelationship < ApplicationRecord
status == "deleted"
end
def is_pending?
status == "pending"
end
def is_active?
status == "active"
end
@@ -74,11 +69,6 @@ class TagRelationship < ApplicationRecord
where(field => Tag.search(params).reorder(nil).select(:name))
end
def pending_first
# unknown statuses return null and are sorted first
order(Arel.sql("array_position(array['pending', 'active', 'deleted', 'retired'], status::text) NULLS FIRST, id DESC"))
end
def search(params)
q = super
q = q.search_attributes(params, :antecedent_name, :consequent_name)
@@ -107,8 +97,6 @@ class TagRelationship < ApplicationRecord
q = q.order("antecedent_name asc, consequent_name asc")
when "tag_count"
q = q.joins(:consequent_tag).order("tags.post_count desc, antecedent_name asc, consequent_name asc")
when "status"
q = q.pending_first
else
q = q.apply_default_order(params)
end
@@ -144,6 +132,10 @@ class TagRelationship < ApplicationRecord
end
end
def self.approve!(antecedent_name:, consequent_name:, approver:, forum_topic: nil)
ProcessTagRelationshipJob.perform_later(class_name: self.name, approver: approver, antecedent_name: antecedent_name, consequent_name: consequent_name, forum_topic: forum_topic)
end
def self.model_restriction(table)
super.where(table[:status].eq("active"))
end