diff --git a/app/models/dialog_field_association_validator.rb b/app/models/dialog_field_association_validator.rb index d8ade8523b6b..067b96294e5e 100644 --- a/app/models/dialog_field_association_validator.rb +++ b/app/models/dialog_field_association_validator.rb @@ -14,15 +14,19 @@ def circular_references(associations) private def initial_paths(associations) - associations.flat_map { |key, values| values.map { |value| [key, value] } } + associations.flat_map { |key, values| values.map { |value| [key, value] if associations.key?(value) } }.compact end def walk_value_path(fieldname_being_triggered, associations, path) - while associations[fieldname_being_triggered].present? - return [fieldname_being_triggered, associations[fieldname_being_triggered].first] if path.include?(associations[fieldname_being_triggered].first) - path << associations[fieldname_being_triggered] - path.flatten! - fieldname_being_triggered = path.last + while associations[fieldname_being_triggered] + return [fieldname_being_triggered, (path & associations[fieldname_being_triggered]).first] if (path & associations[fieldname_being_triggered]).present? + + associations[fieldname_being_triggered].map do |new_element| + path_copy = path.dup + path_copy << new_element + fieldname_being_triggered = new_element + walk_value_path(fieldname_being_triggered, associations, path_copy) + end end end end diff --git a/spec/models/dialog_field_association_validator_spec.rb b/spec/models/dialog_field_association_validator_spec.rb index d393f6885a05..f616abe9d64d 100644 --- a/spec/models/dialog_field_association_validator_spec.rb +++ b/spec/models/dialog_field_association_validator_spec.rb @@ -12,9 +12,12 @@ context "when the associations are not blank" do context "when there are no circular references" do - it "returns false" do + it "returns false on the trivial case" do expect(dialog_field_association_validator.circular_references("foo" => ["baz"])).to eq(false) - expect(dialog_field_association_validator.circular_references("foo" => %w(foo2 foo4), "foo2" => ["foo3"], "foo3" => ["foo4"])).to eq(false) + end + + it "returns false on the non-trivial case" do + expect(dialog_field_association_validator.circular_references("e" => ["c"], "c" => ["a", "d"], "d" => ["a"])).to eq(false) end end