From 683fa62ea5adc874bd40b3b501e05c07dda92603 Mon Sep 17 00:00:00 2001 From: Alex Carruthers Date: Mon, 27 Jan 2025 14:22:16 -0500 Subject: [PATCH] Make it so that the activemodel validations return the correct error types --- lib/measured/rails/validations.rb | 6 +++--- test/rails/validation_test.rb | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/lib/measured/rails/validations.rb b/lib/measured/rails/validations.rb index 5e93498..8b5ea1f 100644 --- a/lib/measured/rails/validations.rb +++ b/lib/measured/rails/validations.rb @@ -24,11 +24,11 @@ def validate_each(record, attribute, measurable) return unless measurable_unit_name.present? || measurable_value.present? measurable_unit = measured_class.unit_system.unit_for(measurable_unit_name) - record.errors.add(attribute, message(record, "is not a valid unit")) unless measurable_unit + record.errors.add(attribute, :invalid, message: message(record, "is not a valid unit")) unless measurable_unit if options[:units] && measurable_unit.present? valid_units = Array(options[:units]).map { |unit| measured_class.unit_system.unit_for(unit) } - record.errors.add(attribute, message(record, "is not a valid unit")) unless valid_units.include?(measurable_unit) + record.errors.add(attribute, :invalid, message: message(record, "is not a valid unit")) unless valid_units.include?(measurable_unit) end if measurable_unit && measurable_value.present? @@ -36,7 +36,7 @@ def validate_each(record, attribute, measurable) comparable_value = value_for(value, record) comparable_value = measured_class.new(comparable_value, measurable_unit) unless comparable_value.is_a?(Measured::Measurable) unless measurable.public_send(CHECKS[option], comparable_value) - record.errors.add(attribute, message(record, "#{measurable.to_s} must be #{CHECKS[option]} #{comparable_value}")) + record.errors.add(attribute, option, message: message(record, "#{measurable.to_s} must be #{CHECKS[option]} #{comparable_value}")) end end end diff --git a/test/rails/validation_test.rb b/test/rails/validation_test.rb index afc69c6..f8c3b36 100644 --- a/test/rails/validation_test.rb +++ b/test/rails/validation_test.rb @@ -39,6 +39,12 @@ class Measured::Rails::ValidationTest < ActiveSupport::TestCase assert_equal ["Length is not a valid unit"], thing.errors.full_messages end + test "validation sets error codes when unit is invalid" do + thing.length_unit = "junk" + refute thing.valid? + assert thing.errors.of_kind?(:length, :invalid) + end + test "validation can override the message with a static string" do thing.length_message_unit = "junk" refute thing.valid? @@ -181,6 +187,28 @@ class Measured::Rails::ValidationTest < ActiveSupport::TestCase refute thing.valid? end + test "validation for numericality puts the proper error types" do + thing.length_numericality_inclusive_value = 5 + refute thing.valid? + assert thing.errors.of_kind?(:length_numericality_inclusive, :greater_than_or_equal_to) + + thing.length_numericality_inclusive_value = 25 + refute thing.valid? + assert thing.errors.of_kind?(:length_numericality_inclusive, :less_than_or_equal_to) + + thing.length_numericality_exclusive_value = 2 + refute thing.valid? + assert thing.errors.of_kind?(:length_numericality_exclusive, :greater_than) + + thing.length_numericality_exclusive_value = 550 + refute thing.valid? + assert thing.errors.of_kind?(:length_numericality_exclusive, :less_than) + + thing.length_numericality_equality_value = 200 + refute thing.valid? + assert thing.errors.of_kind?(:length_numericality_equality, :equal_to) + end + test "validation for numericality handles a nil unit but a valid value" do thing.length_numericality_exclusive_unit = nil thing.length_numericality_exclusive_value = 1