The name AliasAndImplicationImporter is a holdover from the time before bulk update requests existed. This was a bad name because it doesn't do any actual importing, instead it's used for parsing and executing bulk update requests.
155 lines
4.5 KiB
Ruby
155 lines
4.5 KiB
Ruby
class BulkUpdateRequest < ApplicationRecord
|
|
attr_accessor :title
|
|
attr_accessor :reason
|
|
attr_reader :skip_secondary_validations
|
|
|
|
belongs_to :user
|
|
belongs_to :forum_topic, optional: true
|
|
belongs_to :forum_post, optional: true
|
|
belongs_to :approver, optional: true, class_name: "User"
|
|
|
|
before_validation :normalize_text
|
|
before_validation :update_tags
|
|
validates_presence_of :reason, on: :create
|
|
validates_presence_of :script
|
|
validates_presence_of :title, if: ->(rec) {rec.forum_topic_id.blank?}
|
|
validates_presence_of :forum_topic, if: ->(rec) {rec.forum_topic_id.present?}
|
|
validates_inclusion_of :status, :in => %w(pending approved rejected)
|
|
validate :validate_script, :on => :create
|
|
|
|
after_create :create_forum_topic
|
|
|
|
scope :pending_first, -> { order(Arel.sql("(case status when 'pending' then 0 when 'approved' then 1 else 2 end)")) }
|
|
scope :pending, -> {where(status: "pending")}
|
|
scope :approved, -> { where(status: "approved") }
|
|
scope :rejected, -> { where(status: "rejected") }
|
|
scope :has_topic, -> { where.not(forum_topic: nil) }
|
|
scope :expired, -> {where("created_at < ?", TagRelationship::EXPIRY.days.ago)}
|
|
scope :old, -> {where("created_at between ? and ?", TagRelationship::EXPIRY.days.ago, TagRelationship::EXPIRY_WARNING.days.ago)}
|
|
|
|
module SearchMethods
|
|
def default_order
|
|
pending_first.order(id: :desc)
|
|
end
|
|
|
|
def search(params = {})
|
|
q = super
|
|
|
|
q = q.search_attributes(params, :user, :approver, :forum_topic_id, :forum_post_id, :script, :tags)
|
|
q = q.text_attribute_matches(:script, params[:script_matches])
|
|
|
|
if params[:status].present?
|
|
q = q.where(status: params[:status].split(","))
|
|
end
|
|
|
|
params[:order] ||= "status_desc"
|
|
case params[:order]
|
|
when "id_desc"
|
|
q = q.order(id: :desc)
|
|
when "id_asc"
|
|
q = q.order(id: :asc)
|
|
when "updated_at_desc"
|
|
q = q.order(updated_at: :desc)
|
|
when "updated_at_asc"
|
|
q = q.order(updated_at: :asc)
|
|
else
|
|
q = q.apply_default_order(params)
|
|
end
|
|
|
|
q
|
|
end
|
|
end
|
|
|
|
module ApprovalMethods
|
|
def forum_updater
|
|
@forum_updater ||= begin
|
|
post = if forum_topic
|
|
forum_post || forum_topic.forum_posts.first
|
|
else
|
|
nil
|
|
end
|
|
ForumUpdater.new(forum_topic, forum_post: post)
|
|
end
|
|
end
|
|
|
|
def approve!(approver)
|
|
transaction do
|
|
CurrentUser.scoped(approver) do
|
|
processor.process!(approver)
|
|
update!(status: "approved", approver: approver, skip_secondary_validations: true)
|
|
forum_updater.update("The #{bulk_update_request_link} (forum ##{forum_post.id}) has been approved by @#{approver.name}.")
|
|
end
|
|
end
|
|
rescue BulkUpdateRequestProcessor::Error => x
|
|
self.approver = approver
|
|
CurrentUser.scoped(approver) do
|
|
forum_updater.update("The #{bulk_update_request_link} (forum ##{forum_post.id}) has failed: #{x}")
|
|
end
|
|
end
|
|
|
|
def create_forum_topic
|
|
CurrentUser.as(user) do
|
|
body = "[bur:#{id}]\n\n#{reason}"
|
|
self.forum_topic = ForumTopic.create(title: title, category_id: 1, creator: user) unless forum_topic.present?
|
|
self.forum_post = forum_topic.forum_posts.create(body: body, creator: user) unless forum_post.present?
|
|
save
|
|
end
|
|
end
|
|
|
|
def reject!(rejector = User.system)
|
|
transaction do
|
|
update!(status: "rejected")
|
|
forum_updater.update("The #{bulk_update_request_link} (forum ##{forum_post.id}) has been rejected by @#{rejector.name}.")
|
|
end
|
|
end
|
|
|
|
def bulk_update_request_link
|
|
%{"bulk update request ##{id}":/bulk_update_requests?search%5Bid%5D=#{id}}
|
|
end
|
|
end
|
|
|
|
module ValidationMethods
|
|
def validate_script
|
|
processor.validate!
|
|
rescue BulkUpdateRequestProcessor::Error => e
|
|
errors[:base] << e.message
|
|
end
|
|
end
|
|
|
|
extend SearchMethods
|
|
include ApprovalMethods
|
|
include ValidationMethods
|
|
|
|
def normalize_text
|
|
self.script = script.downcase
|
|
end
|
|
|
|
def update_tags
|
|
self.tags = processor.affected_tags
|
|
end
|
|
|
|
def skip_secondary_validations=(v)
|
|
@skip_secondary_validations = v.to_s.truthy?
|
|
end
|
|
|
|
def processor
|
|
@processor ||= BulkUpdateRequestProcessor.new(script, forum_topic_id: forum_topic_id, skip_secondary_validations: skip_secondary_validations)
|
|
end
|
|
|
|
def is_pending?
|
|
status == "pending"
|
|
end
|
|
|
|
def is_approved?
|
|
status == "approved"
|
|
end
|
|
|
|
def is_rejected?
|
|
status == "rejected"
|
|
end
|
|
|
|
def self.available_includes
|
|
[:user, :forum_topic, :forum_post, :approver]
|
|
end
|
|
end
|