Created
November 30, 2010 00:10
-
-
Save michaeldv/720887 to your computer and use it in GitHub Desktop.
Regression between Rails 3.0.3 and 3.0.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### 1) Added $stderr tracing in gems/activesupport-3.0.3/lib/active_support/xml_mini.rb | |
### | |
FORMATTING = { | |
"symbol" => Proc.new { |symbol| symbol.to_s }, | |
"date" => Proc.new { |date| date.to_s(:db) }, | |
"datetime" => Proc.new { |time| $stderr.puts "3.0.3: time.xmlschema for <#{time.class.inspect}>"; time.xmlschema }, | |
"binary" => Proc.new { |binary| ActiveSupport::Base64.encode64(binary) }, | |
"yaml" => Proc.new { |yaml| yaml.to_yaml } | |
} unless defined?(FORMATTING) | |
### 2) Added $stderr tracing in gems/activesupport-3.0.3/lib/active_support/time_with_zone.rb | |
### | |
def xmlschema(fraction_digits = 0) | |
$stderr.puts "3.0.3: xmlschema..." | |
fraction = if fraction_digits > 0 | |
".%i" % time.usec.to_s[0, fraction_digits] | |
end | |
"#{time.strftime("%Y-%m-%dT%H:%M:%S")}#{fraction}#{formatted_offset(true, 'Z')}" | |
end | |
### 3) Added the same tracing in gems/activesupport-3.0.0 | |
### | |
### Now... In Rails 3.0.0 both :created_at and :updated_at are treated as | |
### <ActiveSupport::TimeWithZone>, so everything is kosher: | |
### | |
Loading development environment (Rails 3.0.0) | |
>> Time.zone = "Pacific Time (US & Canada)" | |
"Pacific Time (US & Canada)" | |
>> a = Account.first | |
Account Load (0.7ms) SELECT `accounts`.* FROM `accounts` WHERE (`accounts`.`deleted_at` IS NULL) LIMIT 1 | |
#<Account:0x00000103afc9c8> { | |
:id => 1, | |
:user_id => 8, | |
:assigned_to => 6, | |
:name => "Walker-Dare", | |
:access => "Public", | |
:website => "http://www.walkerdare.com", | |
:toll_free_phone => "1-800-879-6613", | |
:phone => "(252)282-8860", | |
:fax => "(659)573-1022", | |
:deleted_at => nil, | |
:created_at => Tue, 25 May 2010 02:52:26 PDT -07:00, | |
:updated_at => Tue, 25 May 2010 04:47:39 PDT -07:00, | |
:email => "info@walkerdare.com", | |
:background_info => nil | |
} | |
>> a.updated_at = Time.now | |
2010-11-29 15:40:20 -0800 | |
>> a.to_xml | |
3.0.0: time.xmlschema for <ActiveSupport::TimeWithZone> | |
3.0.0: xmlschema... | |
3.0.0: time.xmlschema for <ActiveSupport::TimeWithZone> | |
3.0.0: xmlschema... | |
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<account>\n <access>Public</access>\n <assigned-to type=\"integer\">6</assigned-to>\n <background-info nil=\"true\"></background-info>\n <created-at type=\"datetime\">2010-05-25T02:52:26-07:00</created-at>\n <deleted-at type=\"datetime\" nil=\"true\"></deleted-at>\n <email>info@walkerdare.com</email>\n <fax>(659)573-1022</fax>\n <id type=\"integer\">1</id>\n <name>Walker-Dare</name>\n <phone>(252)282-8860</phone>\n <toll-free-phone>1-800-879-6613</toll-free-phone>\n <updated-at type=\"datetime\">2010-11-29T15:40:20-08:00</updated-at>\n <user-id type=\"integer\">8</user-id>\n | |
### In Rails 3.0.3 however :updated_at is <ActiveSupport::TimeWithZone> but | |
### :created_at is <Time>, so time.xmlschema invokes default Time.#xmlschema | |
### (in my case it lives in ~/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/time.rb) | |
### | |
Loading development environment (Rails 3.0.3) | |
>> Time.zone = "Pacific Time (US & Canada)" | |
"Pacific Time (US & Canada)" | |
>> a = Account.first | |
Account Load (0.7ms) SELECT `accounts`.* FROM `accounts` WHERE (`accounts`.`deleted_at` IS NULL) LIMIT 1 | |
#<Account:0x000001049cd970> { | |
:id => 1, | |
:user_id => 8, | |
:assigned_to => 6, | |
:name => "Walker-Dare", | |
:access => "Public", | |
:website => "http://www.walkerdare.com", | |
:toll_free_phone => "1-800-879-6613", | |
:phone => "(252)282-8860", | |
:fax => "(659)573-1022", | |
:deleted_at => nil, | |
:created_at => Tue, 25 May 2010 02:52:26 PDT -07:00, | |
:updated_at => Tue, 25 May 2010 04:47:39 PDT -07:00, | |
:email => "info@walkerdare.com", | |
:background_info => nil | |
} | |
>> a.updated_at = Time.now | |
2010-11-29 15:49:18 -0800 | |
>> a.to_xml | |
3.0.3: time.xmlschema for <Time> ### <--- REGRESSION! | |
1.9.1: xmlschema... ### <--- Default Time#xmlschema | |
3.0.3: time.xmlschema for <ActiveSupport::TimeWithZone> | |
3.0.3: xmlschema... | |
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<account>\n <access>Public</access>\n <assigned-to type=\"integer\">6</assigned-to>\n <background-info nil=\"true\"></background-info>\n <created-at type=\"datetime\">2010-05-25T09:52:26Z</created-at>\n <deleted-at type=\"datetime\" nil=\"true\"></deleted-at>\n <email>info@walkerdare.com</email>\n <fax>(659)573-1022</fax>\n <id type=\"integer\">1</id>\n <name>Walker-Dare</name>\n <phone>(252)282-8860</phone>\n <toll-free-phone>1-800-879-6613</toll-free-phone>\n <updated-at type=\"datetime\">2010-11-29T15:49:18-08:00</updated-at>\n <user-id type=\"integer\">8</user-id>\n <website>http://www.walkerdare.com</website>\n</account>\n" | |
--- | |
In gems/ruby-1.9.2-p0@r3/gems/activemodel-3.0.3/lib/active_model/serializers/xml.rb: | |
def serialize | |
... | |
@builder.tag!(*args) do | |
add_attributes_and_methods | |
... | |
end | |
def add_attributes_and_methods | |
(serializable_attributes + serializable_methods).each do |attribute| | |
... | |
end | |
def serializable_attributes | |
attributes_hash.map do |name, value| | |
self.class::Attribute.new(name, @serializable, value) | |
end | |
end | |
Stay tuned, we are almost there :-) | |
class Serializer #:nodoc: | |
class Attribute #:nodoc: | |
attr_reader :name, :value, :type | |
def initialize(name, serializable, raw_value=nil) | |
@name, @serializable = name, serializable | |
@value = raw_value || @serializable.send(name) # <--- HERE raw_value preserves its class | |
### @value = value || @serializable.send(name) # <--- Rails 3.0.0 code | |
### Rails 3.0.0 was invoking send (since value is not defined), thus converting Time to ActiveSupport::TimeWithZone | |
### | |
### Possible fix: | |
### raw_value = raw_value.in_time_zone if raw_value.respond_to?(:in_time_zone) | |
### | |
@type = compute_type | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment