Reputation: 121
I'd like to make sure certain fields are populated only when the record has another flag set (and vice-versa). However my test is allowing the model to save even at points when I think it should fail.
class Measurement < ApplicationRecord
validates :start_date, presence: true
validates :end_date, presence: true
validates :actual, numericality: true, if: :is_baseline? # baseline must have actual value
validates :forecast, numericality: false, if: :is_baseline? # baseline must not have forecast value
validates :target, numericality: false, unless: :is_target? # only target can have target value
validates :target, numericality: true, if: :is_target? # only target can have target value
belongs_to :measure
belongs_to :organisation
end
First test that fails:
test "can't create an invalid baseline measure" do
measurement = @measure.measurements.new
measurement.organisation = @organisation
measurement.start_date = "2022-01-1"
measurement.end_date = "2022-01-31"
measurement.is_baseline = true
measurement.actual = 1000
measurement.forecast = 1000 # baseline should not have a forecast
assert_not measurement.save, "Invalid Baseline Measurement saved"
end
Second test that fails
test "can't create an invalid interval measure" do
measurement = @measure.measurements.new
measurement.organisation = @organisation
measurement.start_date = "2022-01-1"
measurement.end_date = "2022-01-31"
measurement.forecast = 1000
measurement.target = 1000 # interval should not have a target
assert_not measurement.save, "Invalid Interval Measurement saved"
end
Any idea why these tests are failing?
Upvotes: 1
Views: 175
Reputation: 106912
This is not how these validations work. numericality: false
doesn't validate the opposite but turns the validation off.
But instead, you can use the absence
validator that checks that a value is not set:
validates :actual, numericality: true, if: :is_baseline? # baseline must have actual value
validates :forecast, absence: true, if: :is_baseline? # baseline must not have forecast value
validates :target, absence: true, unless: :is_target? # only target can have target value
validates :target, numericality: true, if: :is_target? # only target can have target value
Upvotes: 2