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:
evazion
2018-12-26 17:30:07 -06:00
parent ca7c56f95f
commit c27ba02b88
4 changed files with 51 additions and 56 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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