Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make it so that the activemodel validations return the correct error types #162

Merged
merged 1 commit into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading