I J'ai résolu cela en ajoutant des getters et setters nommés mydatefield_formatted qui font explicitement ce que je veux, et les utilisent partout. Probablement une liste de courses pour ne pas faire ça mais je l'aime bien alors j'ai pensé que je le laisserais ici.
app/modèles/mymodel.rb
class Mymodel < ActiveRecord::Base
include ValueFormatters
add_value_formatters
etc.
end
lib/value_formatters.rb
module ValueFormatters
extend ActiveSupport::Concern
module ClassMethods
def add_value_formatters
columns.each do |column|
case column.type
when :datetime
define_method("#{column.name}_formatted") { General.format_datetime(self.read_attribute(column.name)) }
define_method("#{column.name}_formatted=") {|value| self.update_attribute(column.name, General.parse_datetime(value)) }
when :date
define_method("#{column.name}_formatted") { General.format_date(self.read_attribute(column.name)) }
define_method("#{column.name}_formatted=") {|value| self.update_attribute(column.name, General.parse_date(value)) }
when :boolean
define_method("#{column.name}_formatted") { General.format_boolean(self.read_attribute(column.name)) }
define_method("#{column.name}_formatted=") {|value| self.update_attribute(column.name, General.parse_boolean(value)) }
else
# do nothing
end unless self.class.respond_to?("#{column.name}_formatted")
end
end
end
end
lib/general.rb
class General
def self.parse_date(value, end_of_day = false)
result = nil
begin
if value.present?
if value.length == 8
result = DateTime.strptime(value, '%d/%m/%y')
if result.year > Time.new.year + 1
result = DateTime.new(result.year - 100, result.month, result.day)
end
else
result = DateTime.strptime(value, '%d/%m/%Y')
end
end
rescue Exception=>e
#
end
result = result + 23.hours + 59.minutes + 59.seconds if result && end_of_day
result
end
def self.parse_datetime(value)
result = nil
begin
if value.present?
result = DateTime.strptime(value, '%d/%m/%Y %H:%M')
result = nil if result < 100.years.ago
end
rescue Exception=>e
#
end
result
end
def self.format_date(value)
value.present? ? value.strftime('%d/%m/%Y') : ''
end
def self.format_datetime(value)
value.present? ? value.strftime('%d/%m/%Y at %H:%M') : ''
end
def self.format_boolean(value, default = nil)
value = default if value == nil
case value
when true
'Yes'
when false
'No'
else
'Unspecified'
end
end
def self.parse_boolean(value, default = false)
case value.to_s.downcase
when 'true'
when 'yes'
when '1'
when 'on'
true
when 'false'
when 'no'
when '0'
when 'off'
false
else
default
end
end
end
rapport avec la question, mais: jj/mm/aaaa est partout, mais le style Amérique, pas seulement la norme au Royaume-Uni – Pierre