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:
@@ -1,7 +0,0 @@
|
||||
class ProcessTagAliasJob < ApplicationJob
|
||||
queue_as :bulk_update
|
||||
|
||||
def perform(tag_alias, approver)
|
||||
tag_alias.process!(approver)
|
||||
end
|
||||
end
|
||||
@@ -1,7 +0,0 @@
|
||||
class ProcessTagImplicationJob < ApplicationJob
|
||||
queue_as :bulk_update
|
||||
|
||||
def perform(tag_implication, approver)
|
||||
tag_implication.process!(approver)
|
||||
end
|
||||
end
|
||||
9
app/jobs/process_tag_relationship_job.rb
Normal file
9
app/jobs/process_tag_relationship_job.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
class ProcessTagRelationshipJob < ApplicationJob
|
||||
queue_as :bulk_update
|
||||
|
||||
def perform(class_name:, approver:, antecedent_name:, consequent_name:, forum_topic: nil)
|
||||
relation_class = Kernel.const_get(class_name)
|
||||
tag_relationship = relation_class.create!(creator: approver, approver: approver, antecedent_name: antecedent_name, consequent_name: consequent_name, forum_topic: forum_topic)
|
||||
tag_relationship.process!
|
||||
end
|
||||
end
|
||||
@@ -4,7 +4,7 @@ class BulkUpdateRequestProcessor
|
||||
class Error < StandardError; end
|
||||
|
||||
attr_reader :bulk_update_request
|
||||
delegate :script, :forum_topic_id, to: :bulk_update_request
|
||||
delegate :script, :forum_topic, to: :bulk_update_request
|
||||
validate :validate_script
|
||||
|
||||
def initialize(bulk_update_request)
|
||||
@@ -105,12 +105,10 @@ class BulkUpdateRequestProcessor
|
||||
commands.map do |command, *args|
|
||||
case command
|
||||
when :create_alias
|
||||
tag_alias = TagAlias.create!(creator: approver, forum_topic_id: forum_topic_id, status: "pending", antecedent_name: args[0], consequent_name: args[1])
|
||||
tag_alias.approve!(approver)
|
||||
TagAlias.approve!(antecedent_name: args[0], consequent_name: args[1], approver: approver, forum_topic: forum_topic)
|
||||
|
||||
when :create_implication
|
||||
tag_implication = TagImplication.create!(creator: approver, forum_topic_id: forum_topic_id, status: "pending", antecedent_name: args[0], consequent_name: args[1])
|
||||
tag_implication.approve!(approver)
|
||||
TagImplication.approve!(antecedent_name: args[0], consequent_name: args[1], approver: approver, forum_topic: forum_topic)
|
||||
|
||||
when :remove_alias
|
||||
tag_alias = TagAlias.active.find_by!(antecedent_name: args[0], consequent_name: args[1])
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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}")
|
||||
|
||||
@@ -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}]])
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<%= f.simple_fields_for :consequent_tag do |fa| %>
|
||||
<%= fa.input :category, label: "To Category", collection: TagCategory.canonical_mapping.to_a, include_blank: true, selected: params.dig(:search, :consequent_tag, :category) %>
|
||||
<% end %>
|
||||
<%= f.input :status, label: "Status", collection: %w[Active Pending Deleted Retired], include_blank: true, selected: params[:search][:status] %>
|
||||
<%= f.input :order, label: "Order", collection: [%w[Created created_at], %w[Updated updated_at], %w[Name name], %w[Tag\ count tag_count], %w[Status status]], include_blank: true, selected: params[:search][:order] %>
|
||||
<%= f.input :status, label: "Status", collection: %w[Active Deleted Retired], include_blank: true, selected: params[:search][:status] %>
|
||||
<%= f.input :order, label: "Order", collection: [%w[Created created_at], %w[Updated updated_at], %w[Name name], %w[Tag\ count tag_count]], include_blank: true, selected: params[:search][:order] %>
|
||||
<%= f.submit "Search" %>
|
||||
<% end %>
|
||||
|
||||
Reference in New Issue
Block a user