Skip to content

Instantly share code, notes, and snippets.

@txus
Created June 16, 2010 22:11
Show Gist options
  • Save txus/441344 to your computer and use it in GitHub Desktop.
Save txus/441344 to your computer and use it in GitHub Desktop.
# Comparison between after_or_equal_to and
# before_or_equal_to behaviors (they should
# be the same, just that the former sends a
# >= and the latter a <=.
class Product < ActiveRecord::Base
validates :expiration_date, :date => {:before_or_equal_to => Time.now}
end
model = Product.new(:expiration_date => Time.now) # Should be valid
model.valid? # => true, as expected
# Now, after_or_equal_to
class Product < ActiveRecord::Base
validates :expiration_date, :date => {:after_or_equal_to => Time.now}
end
model = Product.new(:expiration_date => Time.now) # Should be valid
model.valid? # => false!
# However, an expiration date of Time.now + 1 makes this product valid.
# Let's take a look at the date_validator code behind this:
CHECKS = { :after => :>, :after_or_equal_to => :>=,
:before => :<, :before_or_equal_to => :<=}.freeze
# And for each check of these it does the following:
record.errors.add(...) unless value.send(CHECKS[option], option_value)
# Which means that before_or_equal_to is correctly performing
record.errors.add(...) unless (Time.now).send(:<=, Time.now) # == true
# but after_or_equal_to, doing the same, resolves the expression as false:
record.errors.add(...) unless (Time.now).send(:>=, Time.now) # == false!
# The only thing changing is the >= instead of the <=, but
# still Time.now == Time.now, so I can't understand it. Any ideas?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment