Skip to content

Instantly share code, notes, and snippets.

@darrinholst
Created February 16, 2012 00:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darrinholst/1840422 to your computer and use it in GitHub Desktop.
Save darrinholst/1840422 to your computer and use it in GitHub Desktop.
Rails date handling

requirements

  • Rails 3.2.1
  • column stored as date
  • date entered as text
  • blank/null date allowed
  • validated on input
  • formatted for display
  • using decorator/presenter (i.e. draper)

weirdness

  • checking for blank in the date validator
  • accessing _before_type_cast in the date validator
  • _before_type_cast in the decorator
#wrap this instead of monkey patching it
module Chronic
class << self
alias :old_parse :parse
def parse(value)
return value if value.nil? || value.is_a?(Time) || value.is_a?(Date)
old_parse(value.gsub(/\.\d*$/, "")) #chronic can't handle trailing milliseconds
end
end
end
class DateValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
user_input = record.send("#{attribute}_before_type_cast")
record.errors[attribute] << 'must be a valid date' unless user_input.blank? || Chronic.parse(user_input)
end
end
<%= render "shared/validation_messages", :target => @person %>
<%= form_for @person do |f| %>
<p>
<%= f.text_field :birthdate %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
class Person < ActiveRecord::Base
validates :birthdate, :date => true
end
class PersonDecorator < ApplicationDecorator
decorates :person
def birthdate
format_date(model.birthdate)
end
def birthdate_before_type_cast
format_date(model.birthdate_before_type_cast)
end
private
def format_date(d)
Chronic.parse(d).strftime("%m/%d/%Y") rescue d
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment