refactor forum notifications for tag changes
This commit is contained in:
@@ -323,7 +323,7 @@ class Artist < ActiveRecord::Base
|
||||
# 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", :skip_secondary_validations => true)
|
||||
tag_implication.approve!(CurrentUser.user)
|
||||
tag_implication.approve!(approver: CurrentUser.user)
|
||||
end
|
||||
|
||||
update_column(:is_banned, true)
|
||||
|
||||
@@ -3,6 +3,7 @@ class BulkUpdateRequest < ActiveRecord::Base
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :forum_topic
|
||||
belongs_to :forum_post
|
||||
belongs_to :approver, :class_name => "User"
|
||||
|
||||
validates_presence_of :user
|
||||
@@ -31,63 +32,90 @@ class BulkUpdateRequest < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
module ApprovalMethods
|
||||
def forum_updater
|
||||
@forum_updater ||= begin
|
||||
post = if forum_topic
|
||||
forum_post || forum_topic.posts.first
|
||||
else
|
||||
nil
|
||||
end
|
||||
ForumUpdater.new(
|
||||
forum_topic,
|
||||
forum_post: post,
|
||||
expected_title: title
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def approve!(approver)
|
||||
CurrentUser.scoped(approver) do
|
||||
AliasAndImplicationImporter.new(script, forum_topic_id, "1", true).process!
|
||||
update({ :status => "approved", :approver_id => CurrentUser.id, :skip_secondary_validations => true }, :as => CurrentUser.role)
|
||||
forum_updater.update("[i]UPDATE #{date_timestamp}[/i]: The \"bulk update request ##{id}\":/bulk_update_requests?search%5Bid%5D=#{id} has been approved.", "APPROVED")
|
||||
end
|
||||
|
||||
rescue Exception => x
|
||||
self.approver = approver
|
||||
CurrentUser.scoped(approver) do
|
||||
forum_updater.update("[i]UPDATE #{date_timestamp}[/i]: \"Bulk update request ##{id}\":/bulk_update_requests?search%5Bid%5D=#{id} failed: #{x.to_s}", "FAILED")
|
||||
end
|
||||
end
|
||||
|
||||
def date_timestamp
|
||||
Time.now.strftime("%Y-%m-%d")
|
||||
end
|
||||
|
||||
def create_forum_topic
|
||||
if forum_topic_id
|
||||
update_attributes(:forum_post_id => forum_post.id)
|
||||
else
|
||||
forum_topic = ForumTopic.create(:title => title, :category_id => 1, :original_post_attributes => {:body => reason_with_link})
|
||||
update_attributes(:forum_topic_id => forum_topic.id, :forum_post_id => forum_topic.posts.first.id)
|
||||
end
|
||||
end
|
||||
|
||||
def reject!
|
||||
forum_updater.update("[i]UPDATE #{date_timestamp}[/i]: The \"bulk update request ##{id}\":/bulk_update_requests?search%5Bid%5D=#{id} has been rejected.", "REJECTED")
|
||||
update_attribute(:status, "rejected")
|
||||
end
|
||||
end
|
||||
|
||||
module ValidationMethods
|
||||
def script_formatted_correctly
|
||||
AliasAndImplicationImporter.tokenize(script)
|
||||
return true
|
||||
rescue StandardError => e
|
||||
errors.add(:base, e.message)
|
||||
return false
|
||||
end
|
||||
|
||||
def forum_topic_id_not_invalid
|
||||
if forum_topic_id && !forum_topic
|
||||
errors.add(:base, "Forum topic ID is invalid")
|
||||
end
|
||||
end
|
||||
|
||||
def validate_script
|
||||
begin
|
||||
AliasAndImplicationImporter.new(script, forum_topic_id, "1", skip_secondary_validations).validate!
|
||||
rescue RuntimeError => e
|
||||
self.errors[:base] = e.message
|
||||
return false
|
||||
end
|
||||
|
||||
errors.empty?
|
||||
end
|
||||
end
|
||||
|
||||
extend SearchMethods
|
||||
|
||||
def approve!(approver)
|
||||
AliasAndImplicationImporter.new(script, forum_topic_id, "1", true).process!(approver)
|
||||
|
||||
update({ :status => "approved", :approver_id => approver.id, :skip_secondary_validations => true }, :as => approver.role)
|
||||
update_forum_topic_for_approve
|
||||
|
||||
rescue Exception => x
|
||||
self.approver = approver
|
||||
message_approver_on_failure(x)
|
||||
update_topic_on_failure(x)
|
||||
end
|
||||
|
||||
def message_approver_on_failure(x)
|
||||
msg = <<-EOS
|
||||
Bulk Update Request ##{id} failed\n
|
||||
Exception: #{x.class}\n
|
||||
Message: #{x.to_s}\n
|
||||
Stack trace:\n
|
||||
EOS
|
||||
|
||||
x.backtrace.each do |line|
|
||||
msg += "#{line}\n"
|
||||
end
|
||||
|
||||
dmail = Dmail.new(
|
||||
:from_id => approver.id,
|
||||
:to_id => approver.id,
|
||||
:owner_id => approver.id,
|
||||
:title => "Bulk update request approval failed",
|
||||
:body => msg
|
||||
)
|
||||
dmail.owner_id = approver.id
|
||||
dmail.save
|
||||
end
|
||||
|
||||
def update_topic_on_failure(x)
|
||||
if forum_topic_id
|
||||
body = "\"Bulk update request ##{id}\":/bulk_update_requests?search%5Bid%5D=#{id} failed: #{x.to_s}"
|
||||
ForumPost.create(:body => body, :topic_id => forum_topic_id)
|
||||
end
|
||||
end
|
||||
include ApprovalMethods
|
||||
include ValidationMethods
|
||||
|
||||
def editable?(user)
|
||||
user_id == user.id || user.is_builder?
|
||||
end
|
||||
|
||||
def create_forum_topic
|
||||
if forum_topic_id
|
||||
ForumPost.create(:body => reason_with_link, :topic_id => forum_topic_id)
|
||||
else
|
||||
forum_topic = ForumTopic.create(:title => "[bulk] #{title}", :category_id => 1, :original_post_attributes => {:body => reason_with_link})
|
||||
update_attribute(:forum_topic_id, forum_topic.id)
|
||||
end
|
||||
end
|
||||
|
||||
def reason_with_link
|
||||
"#{script_with_links}\n\n\"Link to request\":/bulk_update_requests?search[id]=#{id}\n\n#{reason}"
|
||||
end
|
||||
@@ -109,46 +137,11 @@ class BulkUpdateRequest < ActiveRecord::Base
|
||||
lines.join("\n")
|
||||
end
|
||||
|
||||
def reject!
|
||||
update_forum_topic_for_reject
|
||||
update_attribute(:status, "rejected")
|
||||
end
|
||||
|
||||
def initialize_attributes
|
||||
self.user_id = CurrentUser.user.id unless self.user_id
|
||||
self.status = "pending"
|
||||
end
|
||||
|
||||
def script_formatted_correctly
|
||||
AliasAndImplicationImporter.tokenize(script)
|
||||
return true
|
||||
rescue StandardError => e
|
||||
errors.add(:base, e.message)
|
||||
return false
|
||||
end
|
||||
|
||||
def forum_topic_id_not_invalid
|
||||
if forum_topic_id && !forum_topic
|
||||
errors.add(:base, "Forum topic ID is invalid")
|
||||
end
|
||||
end
|
||||
|
||||
def update_forum_topic_for_approve
|
||||
if forum_topic
|
||||
forum_topic.posts.create(
|
||||
:body => "The \"bulk update request ##{id}\":/bulk_update_requests?search%5Bid%5D=#{id} has been approved."
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def update_forum_topic_for_reject
|
||||
if forum_topic
|
||||
forum_topic.posts.create(
|
||||
:body => "The \"bulk update request ##{id}\":/bulk_update_requests?search%5Bid%5D=#{id} has been rejected."
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def normalize_text
|
||||
self.script = script.downcase
|
||||
end
|
||||
@@ -160,15 +153,4 @@ class BulkUpdateRequest < ActiveRecord::Base
|
||||
@skip_secondary_validations = false
|
||||
end
|
||||
end
|
||||
|
||||
def validate_script
|
||||
begin
|
||||
AliasAndImplicationImporter.new(script, forum_topic_id, "1", skip_secondary_validations).validate!
|
||||
rescue RuntimeError => e
|
||||
self.errors[:base] = e.message
|
||||
return false
|
||||
end
|
||||
|
||||
errors.empty?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -20,6 +20,7 @@ class TagAlias < ActiveRecord::Base
|
||||
belongs_to :creator, :class_name => "User"
|
||||
belongs_to :approver, :class_name => "User"
|
||||
belongs_to :forum_topic
|
||||
belongs_to :forum_post
|
||||
attr_accessible :antecedent_name, :consequent_name, :forum_topic_id, :skip_secondary_validations
|
||||
attr_accessible :status, :approver_id, :as => [:admin]
|
||||
|
||||
@@ -77,8 +78,56 @@ class TagAlias < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
module ApprovalMethods
|
||||
def approve!(update_topic: true, approver: CurrentUser.user)
|
||||
CurrentUser.scoped(approver) do
|
||||
update({ :status => "queued", :approver_id => approver.id }, :as => CurrentUser.role)
|
||||
delay(:queue => "default").process!(update_topic: update_topic)
|
||||
end
|
||||
end
|
||||
|
||||
def approval_message
|
||||
"[i]UPDATE #{date_timestamp}[/i]: The tag alias [[#{antecedent_name}]] -> [[#{consequent_name}]] (alias ##{id}) has been approved."
|
||||
end
|
||||
|
||||
def failure_message(e = nil)
|
||||
"[i]UPDATE #{date_timestamp}[/i]: The tag alias [[#{antecedent_name}]] -> [[#{consequent_name}]] (alias ##{id}) failed during processing. Reason: #{e}"
|
||||
end
|
||||
|
||||
def reject_message
|
||||
"[i]UPDATE #{date_timestamp}[/i]: The tag alias [[#{antecedent_name}]] -> [[#{consequent_name}]] (alias ##{id}) has been rejected."
|
||||
end
|
||||
|
||||
def conflict_message
|
||||
"[i]UPDATE #{date_timestamp}[/i]: The tag alias [[#{antecedent_name}]] -> [[#{consequent_name}]] (alias ##{id}) has conflicting wiki pages. [[#{consequent_name}]] should be updated to include information from [[#{antecedent_name}]] if necessary."
|
||||
end
|
||||
|
||||
def date_timestamp
|
||||
Time.now.strftime("%Y-%m-%d")
|
||||
end
|
||||
end
|
||||
|
||||
module ForumMethods
|
||||
def forum_updater
|
||||
@forum_updater ||= begin
|
||||
post = if forum_topic
|
||||
forum_post || forum_topic.posts.where("body like ?", TagAliasRequest.command_string(antecedent_name, consequent_name) + "%").last
|
||||
else
|
||||
nil
|
||||
end
|
||||
ForumUpdater.new(
|
||||
forum_topic,
|
||||
forum_post: post,
|
||||
expected_title: TagAliasRequest.topic_title(antecedent_name, consequent_name)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
extend SearchMethods
|
||||
include CacheMethods
|
||||
include ApprovalMethods
|
||||
include ForumMethods
|
||||
|
||||
def self.to_aliased(names)
|
||||
Cache.get_multi(Array(names), "ta") do |tag|
|
||||
@@ -86,30 +135,25 @@ class TagAlias < ActiveRecord::Base
|
||||
end.values
|
||||
end
|
||||
|
||||
def approve!(approver = CurrentUser.user, update_topic: true)
|
||||
update({ :status => "queued", :approver_id => approver.id }, :as => approver.role)
|
||||
delay(:queue => "default").process!(update_topic)
|
||||
end
|
||||
|
||||
def process!(update_topic=true)
|
||||
def process!(update_topic: true)
|
||||
unless valid?
|
||||
raise errors.full_messages.join("; ")
|
||||
end
|
||||
|
||||
tries = 0
|
||||
forum_message = []
|
||||
messages = []
|
||||
|
||||
begin
|
||||
CurrentUser.scoped(approver, CurrentUser.ip_addr) do
|
||||
update({ :status => "processing" }, :as => approver.role)
|
||||
update({ :status => "processing" }, :as => CurrentUser.role)
|
||||
move_aliases_and_implications
|
||||
move_saved_searches
|
||||
clear_all_cache
|
||||
ensure_category_consistency
|
||||
update_posts
|
||||
forum_message << "The tag alias [[#{antecedent_name}]] -> [[#{consequent_name}]] (alias ##{id}) has been approved."
|
||||
forum_message << rename_wiki_and_artist
|
||||
update({ :status => "active", :post_count => consequent_tag.post_count }, :as => approver.role)
|
||||
forum_updater.update(approval_message, "APPROVED") if update_topic
|
||||
rename_wiki_and_artist
|
||||
update({ :status => "active", :post_count => consequent_tag.post_count }, :as => CurrentUser.role)
|
||||
end
|
||||
rescue Exception => e
|
||||
if tries < 5
|
||||
@@ -118,18 +162,14 @@ class TagAlias < ActiveRecord::Base
|
||||
retry
|
||||
end
|
||||
|
||||
forum_message << "The tag alias [[#{antecedent_name}]] -> [[#{consequent_name}]] (alias ##{id}) failed during processing. Reason: #{e}"
|
||||
update({ :status => "error: #{e}" }, :as => approver.role)
|
||||
CurrentUser.scoped(approver, CurrentUser.ip_addr) do
|
||||
forum_updater.update(failure_message(e), "FAILED") if update_topic
|
||||
update({ :status => "error: #{e}" }, :as => CurrentUser.role)
|
||||
end
|
||||
|
||||
if Rails.env.production?
|
||||
NewRelic::Agent.notice_error(e, :custom_params => {:tag_alias_id => id, :antecedent_name => antecedent_name, :consequent_name => consequent_name})
|
||||
end
|
||||
ensure
|
||||
if update_topic && forum_topic.present?
|
||||
CurrentUser.scoped(approver, CurrentUser.ip_addr) do
|
||||
forum_topic.posts.create(:body => forum_message.join("\n\n"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -248,8 +288,6 @@ class TagAlias < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def rename_wiki_and_artist
|
||||
message = ""
|
||||
|
||||
antecedent_wiki = WikiPage.titled(antecedent_name).first
|
||||
if antecedent_wiki.present?
|
||||
if WikiPage.titled(consequent_name).blank?
|
||||
@@ -257,7 +295,7 @@ class TagAlias < ActiveRecord::Base
|
||||
antecedent_wiki.update(title: consequent_name, skip_secondary_validations: true)
|
||||
end
|
||||
else
|
||||
message = "The tag alias [[#{antecedent_name}]] -> [[#{consequent_name}]] (alias ##{id}) has conflicting wiki pages. [[#{consequent_name}]] should be updated to include information from [[#{antecedent_name}]] if necessary."
|
||||
forum_updater.update(conflict_message)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -271,8 +309,6 @@ class TagAlias < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
message
|
||||
end
|
||||
|
||||
def deletable_by?(user)
|
||||
@@ -286,18 +322,10 @@ class TagAlias < ActiveRecord::Base
|
||||
deletable_by?(user)
|
||||
end
|
||||
|
||||
def update_forum_topic_for_reject
|
||||
if forum_topic
|
||||
forum_topic.posts.create(
|
||||
:body => "The tag alias [[#{antecedent_name}]] -> [[#{consequent_name}]] (alias ##{id}) has been rejected."
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def reject!
|
||||
update({ :status => "deleted", }, :as => CurrentUser.role)
|
||||
update({ :status => "deleted" }, :as => CurrentUser.role)
|
||||
clear_all_cache
|
||||
update_forum_topic_for_reject
|
||||
forum_updater.update(reject_message, "REJECTED")
|
||||
destroy
|
||||
end
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ class TagImplication < ActiveRecord::Base
|
||||
belongs_to :creator, :class_name => "User"
|
||||
belongs_to :approver, :class_name => "User"
|
||||
belongs_to :forum_topic
|
||||
belongs_to :forum_post
|
||||
before_validation :initialize_creator, :on => :create
|
||||
before_validation :normalize_names
|
||||
validates_format_of :status, :with => /\A(active|deleted|pending|processing|queued|error: .*)\Z/
|
||||
@@ -127,91 +128,161 @@ class TagImplication < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
module ValidationMethods
|
||||
def absence_of_circular_relation
|
||||
# We don't want a -> b && b -> a chains
|
||||
if self.class.active.exists?(["antecedent_name = ? and consequent_name = ?", consequent_name, antecedent_name])
|
||||
self.errors[:base] << "Tag implication can not create a circular relation with another tag implication"
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def antecedent_is_not_aliased
|
||||
# We don't want to implicate a -> b if a is already aliased to c
|
||||
if TagAlias.active.exists?(["antecedent_name = ?", antecedent_name])
|
||||
self.errors[:base] << "Antecedent tag must not be aliased to another tag"
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def consequent_is_not_aliased
|
||||
# We don't want to implicate a -> b if b is already aliased to c
|
||||
if TagAlias.active.exists?(["antecedent_name = ?", consequent_name])
|
||||
self.errors[:base] << "Consequent tag must not be aliased to another tag"
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def antecedent_and_consequent_are_different
|
||||
normalize_names
|
||||
if antecedent_name == consequent_name
|
||||
self.errors[:base] << "Cannot implicate a tag to itself"
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def wiki_pages_present
|
||||
return if skip_secondary_validations
|
||||
|
||||
unless WikiPage.titled(consequent_name).exists?
|
||||
self.errors[:base] = "The #{consequent_name} tag needs a corresponding wiki page"
|
||||
return false
|
||||
end
|
||||
|
||||
unless WikiPage.titled(antecedent_name).exists?
|
||||
self.errors[:base] = "The #{antecedent_name} tag needs a corresponding wiki page"
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module ApprovalMethods
|
||||
def process!(update_topic: true)
|
||||
unless valid?
|
||||
raise errors.full_messages.join("; ")
|
||||
end
|
||||
|
||||
tries = 0
|
||||
|
||||
begin
|
||||
CurrentUser.scoped(approver, CurrentUser.ip_addr) do
|
||||
update({ :status => "processing" }, :as => CurrentUser.role)
|
||||
update_posts
|
||||
update({ :status => "active" }, :as => CurrentUser.role)
|
||||
update_descendant_names_for_parents
|
||||
forum_updater.update("[i]UPDATE #{date_timestamp}[/i]: The tag implication #{antecedent_name} -> #{consequent_name} has been approved.", "APPROVED") if update_topic
|
||||
end
|
||||
rescue Exception => e
|
||||
if tries < 5
|
||||
tries += 1
|
||||
sleep 2 ** tries
|
||||
retry
|
||||
end
|
||||
|
||||
forum_updater.update("[i]UPDATE #{date_timestamp}[/i]: The tag implication #{antecedent_name} -> #{consequent_name} failed during processing. Reason: #{e}", "FAILED") if update_topic
|
||||
update({ :status => "error: #{e}" }, :as => CurrentUser.role)
|
||||
|
||||
if Rails.env.production?
|
||||
NewRelic::Agent.notice_error(e, :custom_params => {:tag_implication_id => id, :antecedent_name => antecedent_name, :consequent_name => consequent_name})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update_posts
|
||||
Post.without_timeout do
|
||||
Post.raw_tag_match(antecedent_name).where("true /* TagImplication#update_posts */").find_each do |post|
|
||||
fixed_tags = "#{post.tag_string} #{descendant_names}".strip
|
||||
CurrentUser.scoped(creator, creator_ip_addr) do
|
||||
post.update_attributes(
|
||||
:tag_string => fixed_tags
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def approve!(approver: CurrentUser.user, update_topic: true)
|
||||
update({ :status => "queued", :approver_id => approver.id }, :as => approver.role)
|
||||
delay(:queue => "default").process!(update_topic: update_topic)
|
||||
end
|
||||
|
||||
def reject!
|
||||
update({ :status => "deleted", }, :as => CurrentUser.role)
|
||||
forum_updater.update("[i]UPDATE #{date_timestamp}[/i]: The tag implication #{antecedent_name} -> #{consequent_name} has been rejected.", "REJECTED")
|
||||
destroy
|
||||
end
|
||||
|
||||
def create_mod_action
|
||||
implication = %Q("tag implication ##{id}":[#{Rails.application.routes.url_helpers.tag_implication_path(self)}]: [[#{antecedent_name}]] -> [[#{consequent_name}]])
|
||||
|
||||
if id_changed?
|
||||
ModAction.log("created #{status} #{implication}")
|
||||
else
|
||||
# format the changes hash more nicely.
|
||||
change_desc = changes.except(:updated_at).map do |attribute, values|
|
||||
old, new = values[0], values[1]
|
||||
if old.nil?
|
||||
%Q(set #{attribute} to "#{new}")
|
||||
else
|
||||
%Q(changed #{attribute} from "#{old}" to "#{new}")
|
||||
end
|
||||
end.join(", ")
|
||||
|
||||
ModAction.log("updated #{implication}\n#{change_desc}")
|
||||
end
|
||||
end
|
||||
|
||||
def date_timestamp
|
||||
Time.now.strftime("%Y-%m-%d")
|
||||
end
|
||||
|
||||
def forum_updater
|
||||
@forum_updater ||= begin
|
||||
post = if forum_topic
|
||||
forum_post || forum_topic.posts.where("body like ?", TagImplicationRequest.command_string(antecedent_name, consequent_name) + "%").last
|
||||
else
|
||||
nil
|
||||
end
|
||||
ForumUpdater.new(
|
||||
forum_topic,
|
||||
forum_post: post,
|
||||
expected_title: TagImplicationRequest.topic_title(antecedent_name, consequent_name)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
include DescendantMethods
|
||||
include ParentMethods
|
||||
extend SearchMethods
|
||||
include ValidationMethods
|
||||
include ApprovalMethods
|
||||
|
||||
def initialize_creator
|
||||
self.creator_id = CurrentUser.user.id
|
||||
self.creator_ip_addr = CurrentUser.ip_addr
|
||||
end
|
||||
|
||||
def process!(update_topic=true)
|
||||
unless valid?
|
||||
raise errors.full_messages.join("; ")
|
||||
end
|
||||
|
||||
tries = 0
|
||||
|
||||
begin
|
||||
CurrentUser.scoped(approver, CurrentUser.ip_addr) do
|
||||
update({ :status => "processing" }, :as => approver.role)
|
||||
update_posts
|
||||
update({ :status => "active" }, :as => approver.role)
|
||||
update_descendant_names_for_parents
|
||||
update_forum_topic_for_approve if update_topic
|
||||
end
|
||||
rescue Exception => e
|
||||
if tries < 5
|
||||
tries += 1
|
||||
sleep 2 ** tries
|
||||
retry
|
||||
end
|
||||
|
||||
update_forum_topic_for_error(e)
|
||||
update({ :status => "error: #{e}" }, :as => CurrentUser.role)
|
||||
|
||||
if Rails.env.production?
|
||||
NewRelic::Agent.notice_error(e, :custom_params => {:tag_implication_id => id, :antecedent_name => antecedent_name, :consequent_name => consequent_name})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def absence_of_circular_relation
|
||||
# We don't want a -> b && b -> a chains
|
||||
if self.class.active.exists?(["antecedent_name = ? and consequent_name = ?", consequent_name, antecedent_name])
|
||||
self.errors[:base] << "Tag implication can not create a circular relation with another tag implication"
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def antecedent_is_not_aliased
|
||||
# We don't want to implicate a -> b if a is already aliased to c
|
||||
if TagAlias.active.exists?(["antecedent_name = ?", antecedent_name])
|
||||
self.errors[:base] << "Antecedent tag must not be aliased to another tag"
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def consequent_is_not_aliased
|
||||
# We don't want to implicate a -> b if b is already aliased to c
|
||||
if TagAlias.active.exists?(["antecedent_name = ?", consequent_name])
|
||||
self.errors[:base] << "Consequent tag must not be aliased to another tag"
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def antecedent_and_consequent_are_different
|
||||
normalize_names
|
||||
if antecedent_name == consequent_name
|
||||
self.errors[:base] << "Cannot implicate a tag to itself"
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def update_posts
|
||||
Post.without_timeout do
|
||||
Post.raw_tag_match(antecedent_name).where("true /* TagImplication#update_posts */").find_each do |post|
|
||||
fixed_tags = "#{post.tag_string} #{descendant_names}".strip
|
||||
CurrentUser.scoped(creator, creator_ip_addr) do
|
||||
post.update_attributes(
|
||||
:tag_string => fixed_tags
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def normalize_names
|
||||
self.antecedent_name = antecedent_name.downcase.tr(" ", "_")
|
||||
self.consequent_name = consequent_name.downcase.tr(" ", "_")
|
||||
@@ -249,73 +320,4 @@ class TagImplication < ActiveRecord::Base
|
||||
def editable_by?(user)
|
||||
deletable_by?(user)
|
||||
end
|
||||
|
||||
def update_forum_topic_for_approve
|
||||
if forum_topic
|
||||
forum_topic.posts.create(
|
||||
:body => "The tag implication #{antecedent_name} -> #{consequent_name} has been approved."
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def update_forum_topic_for_reject
|
||||
if forum_topic
|
||||
forum_topic.posts.create(
|
||||
:body => "The tag implication #{antecedent_name} -> #{consequent_name} has been rejected."
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def update_forum_topic_for_error(e)
|
||||
if forum_topic
|
||||
forum_topic.posts.create(
|
||||
:body => "The tag implication #{antecedent_name} -> #{consequent_name} failed during processing. Reason: #{e}"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def wiki_pages_present
|
||||
return if skip_secondary_validations
|
||||
|
||||
unless WikiPage.titled(consequent_name).exists?
|
||||
self.errors[:base] = "The #{consequent_name} tag needs a corresponding wiki page"
|
||||
return false
|
||||
end
|
||||
|
||||
unless WikiPage.titled(antecedent_name).exists?
|
||||
self.errors[:base] = "The #{antecedent_name} tag needs a corresponding wiki page"
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def approve!(approver = CurrentUser.user, update_topic: true)
|
||||
update({ :status => "queued", :approver_id => approver.id }, :as => approver.role)
|
||||
delay(:queue => "default").process!(update_topic)
|
||||
end
|
||||
|
||||
def reject!
|
||||
update({ :status => "deleted", }, :as => CurrentUser.role)
|
||||
update_forum_topic_for_reject
|
||||
destroy
|
||||
end
|
||||
|
||||
def create_mod_action
|
||||
implication = %Q("tag implication ##{id}":[#{Rails.application.routes.url_helpers.tag_implication_path(self)}]: [[#{antecedent_name}]] -> [[#{consequent_name}]])
|
||||
|
||||
if id_changed?
|
||||
ModAction.log("created #{status} #{implication}")
|
||||
else
|
||||
# format the changes hash more nicely.
|
||||
change_desc = changes.except(:updated_at).map do |attribute, values|
|
||||
old, new = values[0], values[1]
|
||||
if old.nil?
|
||||
%Q(set #{attribute} to "#{new}")
|
||||
else
|
||||
%Q(changed #{attribute} from "#{old}" to "#{new}")
|
||||
end
|
||||
end.join(", ")
|
||||
|
||||
ModAction.log("updated #{implication}\n#{change_desc}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user