Skip to content

Commit

Permalink
Merge pull request #162 from Shopify/fix-model-validation-error-types
Browse files Browse the repository at this point in the history
Make it so that the activemodel validations return the correct error types
  • Loading branch information
alexcarruthers authored Jan 27, 2025
2 parents 4af4080 + 683fa62 commit edc12bf
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
6 changes: 3 additions & 3 deletions lib/measured/rails/validations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ 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?
options.slice(*CHECKS.keys).each do |option, value|
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
Expand Down
28 changes: 28 additions & 0 deletions test/rails/validation_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit edc12bf

Please sign in to comment.