问题
By default, the datetime field from the database is being converted and stripping off the milliseconds:
some_datetime => "2009-11-11T02:19:36Z"
attribute_before_type_cast('some_datetime') => "2009-11-11 02:19:36.145"
If I try to overrride the accessor for this attribute like;
def some_datetime
attribute_before_type_cast('some_datetime')
end
when I try "to_xml" for that model, I get the following error:
NoMethodError (undefined method `xmlschema' for "2009-11-11 02:19:36.145":String):
I have tried to parse the String to a Time object but can't get one to include the milliseconds;
def some_datetime
Time.parse(attribute_before_type_cast('some_datetime').sub(/\s/,"T").sub(/$/,"Z"))
end
Can anyone help get get a datetime with milliseconds rendered by to_xml?
回答1:
As it turns out, I can exclude the original datetime field, and add a custom method which in turn renders the datetime as a string to the to_xml. This feels hackish, but it's working.. Is there another way to get milliseconds directly in the original datetime field?
In each model, I exclude "except" the field names that have datetimes that I want changed, and I include "methods" with the same name returning the attribute before it is typecasted.
def to_xml(options = {})
options[:methods] = [:some_datetime]
options[:except] = [:some_datetime]
super
end
def some_datetime
attribute_before_type_cast('some_datetime')
end
Rendering to_xml is working great with models included and any other options I pass in.
回答2:
I have started to learn Ruby and was impressed by Mats "Principle of Least Surprise".
But the Date and Time implementation in Ruby ( and Rails ) is full of surprises:
Starting with a plain irb:
require 'time'
=> true
dt = Time.now
=> 2010-05-31 17:18:39 +0100
Time.parse(dt.to_s) == dt
=> false !?!?!?!?
dt.to_s(:db)
ArgumentError: wrong number of arguments(1 for 0)
from (irb):5:into_s'
'
from (irb):5
from C:/Ruby19/bin/irb:12:in
ok lets take some Rails:
sqlserver_test/development?: dt2 = Time.zone.now
=> Mon, 31 May 2010 17:24:54 CEST +02:00
sqlserver_test/development: dt2.class
=> ActiveSupport::TimeWithZone
sqlserver_test/development: Time.zone.parse(dt2.to_s) == dt2
=> false
sqlserver_test/development: dt2.to_s(:db)
=> "2010-05-31 15:24:54"
sqlserver_test/development: dt2.to_s(:iso8601)
=> "2010-05-31 17:24:54 +0200"
sqlserver_test/development: dt2.to_s(:iso8601) == dt2.iso8601
=> false
( all running on Ruby 1.9.1 with Rails 2.3.5 on Windows Xp )
Currently I only find several "hacks" regarding DateTime fields and databases but no clean solution WITHOUT surprises ...
来源:https://stackoverflow.com/questions/2403794/xml-serialization-is-not-including-milliseconds-in-datetime-field-from-rails-mod