aliases/implications: clean up validations.
* Don't return true/false in validations (does nothing). * Prefer `errors[:base]` over `self.errors[:base]`. * Add antecedent_wiki / consequent_wiki associations. * Factor out antecedent_and_consequent_are_different validation.
This commit is contained in:
@@ -6,9 +6,8 @@ class TagAlias < TagRelationship
|
||||
after_save :create_mod_action
|
||||
validates_uniqueness_of :antecedent_name
|
||||
validate :absence_of_transitive_relation
|
||||
validate :antecedent_and_consequent_are_different
|
||||
validate :consequent_has_wiki_page, :on => :create
|
||||
validate :mininum_antecedent_count, :on => :create
|
||||
validate :consequent_has_wiki_page, on: :create, unless: :skip_secondary_validations
|
||||
validate :mininum_antecedent_count, on: :create, unless: :skip_secondary_validations
|
||||
|
||||
module CacheMethods
|
||||
extend ActiveSupport::Concern
|
||||
@@ -101,17 +100,8 @@ class TagAlias < TagRelationship
|
||||
def absence_of_transitive_relation
|
||||
# We don't want a -> b && b -> c chains if the b -> c alias was created first.
|
||||
# If the a -> b alias was created first, the new one will be allowed and the old one will be moved automatically instead.
|
||||
if self.class.active.exists?(["antecedent_name = ?", consequent_name])
|
||||
self.errors[:base] << "A tag alias for #{consequent_name} already exists"
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def antecedent_and_consequent_are_different
|
||||
normalize_names
|
||||
if antecedent_name == consequent_name
|
||||
self.errors[:base] << "Cannot alias a tag to itself"
|
||||
false
|
||||
if TagAlias.active.exists?(antecedent_name: consequent_name)
|
||||
errors[:base] << "A tag alias for #{consequent_name} already exists"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -164,8 +154,6 @@ class TagAlias < TagRelationship
|
||||
if antecedent_tag.category != consequent_tag.category && antecedent_tag.category != Tag.categories.general
|
||||
consequent_tag.update_attribute(:category, antecedent_tag.category)
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def update_posts
|
||||
@@ -214,19 +202,14 @@ class TagAlias < TagRelationship
|
||||
end
|
||||
|
||||
def consequent_has_wiki_page
|
||||
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
|
||||
if consequent_wiki.nil?
|
||||
errors[:base] << "The #{consequent_name} tag needs a corresponding wiki page"
|
||||
end
|
||||
end
|
||||
|
||||
def mininum_antecedent_count
|
||||
return if skip_secondary_validations
|
||||
|
||||
unless Post.fast_count(antecedent_name) >= 50
|
||||
self.errors[:base] << "The #{antecedent_name} tag must have at least 50 posts for an alias to be created"
|
||||
if antecedent_tag.post_count < 50
|
||||
errors[:base] << "The #{antecedent_name} tag must have at least 50 posts for an alias to be created"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -12,8 +12,7 @@ class TagImplication < TagRelationship
|
||||
validate :absence_of_transitive_relation
|
||||
validate :antecedent_is_not_aliased
|
||||
validate :consequent_is_not_aliased
|
||||
validate :antecedent_and_consequent_are_different
|
||||
validate :wiki_pages_present, :on => :create
|
||||
validate :wiki_pages_present, on: :create, unless: :skip_secondary_validations
|
||||
scope :old, ->{where("created_at between ? and ?", 2.months.ago, 1.month.ago)}
|
||||
scope :pending, ->{where(status: "pending")}
|
||||
|
||||
@@ -78,9 +77,8 @@ class TagImplication < TagRelationship
|
||||
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
|
||||
if TagImplication.active.exists?(["antecedent_name = ? and consequent_name = ?", consequent_name, antecedent_name])
|
||||
errors[:base] << "Tag implication can not create a circular relation with another tag implication"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -90,45 +88,31 @@ class TagImplication < TagRelationship
|
||||
implications = TagImplication.active.where("antecedent_name = ? and consequent_name != ?", antecedent_name, consequent_name)
|
||||
implied_tags = implications.flat_map(&:descendant_names)
|
||||
if implied_tags.include?(consequent_name)
|
||||
self.errors[:base] << "#{antecedent_name} already implies #{consequent_name} through another implication"
|
||||
errors[:base] << "#{antecedent_name} already implies #{consequent_name} through another implication"
|
||||
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
|
||||
errors[:base] << "Antecedent tag must not be aliased to another tag"
|
||||
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
|
||||
errors[:base] << "Consequent tag must not be aliased to another tag"
|
||||
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
|
||||
if consequent_wiki.blank?
|
||||
errors[:base] << "The #{consequent_name} tag needs a corresponding wiki page"
|
||||
end
|
||||
|
||||
unless WikiPage.titled(antecedent_name).exists?
|
||||
self.errors[:base] << "The #{antecedent_name} tag needs a corresponding wiki page"
|
||||
return false
|
||||
if antecedent_wiki.blank?
|
||||
errors[:base] << "The #{antecedent_name} tag needs a corresponding wiki page"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,6 +12,8 @@ class TagRelationship < ApplicationRecord
|
||||
belongs_to :forum_topic, optional: true
|
||||
has_one :antecedent_tag, :class_name => "Tag", :foreign_key => "name", :primary_key => "antecedent_name"
|
||||
has_one :consequent_tag, :class_name => "Tag", :foreign_key => "name", :primary_key => "consequent_name"
|
||||
has_one :antecedent_wiki, through: :antecedent_tag, source: :wiki_page
|
||||
has_one :consequent_wiki, through: :consequent_tag, source: :wiki_page
|
||||
|
||||
scope :active, ->{where(status: "active")}
|
||||
scope :expired, ->{where("created_at < ?", EXPIRY.days.ago)}
|
||||
@@ -26,6 +28,7 @@ class TagRelationship < ApplicationRecord
|
||||
validates :creator, presence: { message: "must exist" }, if: -> { creator_id.present? }
|
||||
validates :approver, presence: { message: "must exist" }, if: -> { approver_id.present? }
|
||||
validates :forum_topic, presence: { message: "must exist" }, if: -> { forum_topic_id.present? }
|
||||
validate :antecedent_and_consequent_are_different
|
||||
|
||||
def initialize_creator
|
||||
self.creator_id = CurrentUser.user.id
|
||||
@@ -163,6 +166,12 @@ class TagRelationship < ApplicationRecord
|
||||
end
|
||||
end
|
||||
|
||||
def antecedent_and_consequent_are_different
|
||||
if antecedent_name == consequent_name
|
||||
errors[:base] << "Cannot alias or implicate a tag to itself"
|
||||
end
|
||||
end
|
||||
|
||||
extend SearchMethods
|
||||
include MessageMethods
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user