Fix #3200: Disallow creation of superfluous implications.

Disallow transitive implications. If a -> b -> c already exists, don't
allow a -> c.

Caveat: if b -> c already exists, and we make a BUR for a -> b and a -> c,
the BUR validates even though a -> c is redundant. It only fails
when the BUR is approved.
This commit is contained in:
evazion
2017-07-04 17:02:17 -05:00
parent cda35494a4
commit 542c673221
3 changed files with 50 additions and 1 deletions

View File

@@ -18,6 +18,7 @@ class TagImplication < ApplicationRecord
validates :forum_topic, presence: { message: "must exist" }, if: lambda { forum_topic_id.present? }
validates_uniqueness_of :antecedent_name, :scope => :consequent_name
validate :absence_of_circular_relation
validate :absence_of_transitive_relation
validate :antecedent_is_not_aliased
validate :consequent_is_not_aliased
validate :antecedent_and_consequent_are_different
@@ -137,6 +138,16 @@ class TagImplication < ApplicationRecord
end
end
# If we already have a -> b -> c, don't allow a -> c.
def absence_of_transitive_relation
# Find everything else the antecedent implies, not including the current implication.
implications = TagImplication.active.where("antecedent_name = ? and consequent_name != ?", antecedent_name, consequent_name)
implied_tags = implications.flat_map(&:descendant_names_array)
if implied_tags.include?(consequent_name)
self.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])