Skip to content

Commit

Permalink
feat: pass non-reserved validation options to errors
Browse files Browse the repository at this point in the history
  • Loading branch information
adzap committed Dec 31, 2024
1 parent 858b655 commit 40799da
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
19 changes: 14 additions & 5 deletions lib/validates_timeliness/validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class Validator < ActiveModel::EachValidator

RESTRICTION_ERROR_MESSAGE = "Error occurred validating %s for %s restriction:\n%s"

RESERVED_OPTIONS = RESTRICTIONS.keys + RESTRICTIONS.keys.map { |option| :"#{option}_message" }

def self.kind
:timeliness
end
Expand Down Expand Up @@ -72,7 +74,7 @@ def validate_restrictions(record, attr_name, value)
begin
restriction_value = @converter.type_cast_value(@converter.evaluate(options[restriction], record))
unless value.send(RESTRICTIONS[restriction], restriction_value)
add_error(record, attr_name, restriction, restriction_value) and break
add_error(record, attr_name, restriction, value: value, restriction_value: restriction_value) and break
end
rescue => e
unless ValidatesTimeliness.ignore_restriction_errors
Expand All @@ -83,13 +85,20 @@ def validate_restrictions(record, attr_name, value)
end
end

def add_error(record, attr_name, message, value=nil)
value = format_error_value(value) if value
message_options = { message: options.fetch(:"#{message}_message", options[:message]), restriction: value }
record.errors.add(attr_name, message, **message_options)
def add_error(record, attr_name, message, restriction_value: nil, value: nil)
error_options = options.except(*RESERVED_OPTIONS).merge!(
restriction: format_error_value(restriction_value),
value: value
)

message_text = options[:"#{message}_message"]
error_options[:message] = message_text if message_text.present?

record.errors.add(attr_name, message, **error_options)
end

def format_error_value(value)
return unless value
format = I18n.t(@type, default: DEFAULT_ERROR_VALUE_FORMATS[@type], scope: 'validates_timeliness.error_value_formats')
value.strftime(format)
end
Expand Down
20 changes: 20 additions & 0 deletions spec/validates_timeliness/validator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,26 @@ class PersonWithFormatOption
end
end

describe "custom option" do
it "should pass custom options to the error" do
Person.validates_datetime :birth_datetime, :on_or_before => Time.utc(2010,1,2,3,4,5), :custom => 'option'

with_each_model_value(:birth_datetime, Time.utc(2010,1,2,3,4,5,10000), Person) do |record, value|
expect(record).to_not be_valid
expect(record.errors.where(:birth_datetime).first.options).to include(custom: 'option')
end
end

it "should not pass config options to the error" do
Person.validates_datetime :birth_datetime, :on_or_before => Time.utc(2010,1,2,3,4,5), :custom => 'option'

with_each_model_value(:birth_datetime, Time.utc(2010,1,2,3,4,5,10000), Person) do |record, value|
expect(record).to_not be_valid
expect(record.errors.where(:birth_datetime).first.options.keys).to_not include(:on_or_before)
end
end
end

describe "restriction value errors" do
let(:person) { Person.new(:birth_date => Date.today) }

Expand Down

0 comments on commit 40799da

Please sign in to comment.