Forum: Ruby on Rails Time Zone / Active Record Persistence Error (Windows Only)

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
1cf29a73259983fed1fe3f8acb0819a2?d=identicon&s=25 John Hohlen (hohlen)
on 2008-11-15 06:47
Attachment: error.txt (60 KB)
The error below has been encountered using both Rails 2.1.1 and 2.1.2.

I have a strange Time Zone / Active Record persistence error that only
occurs on Windows (it works fine on OS X).  In addition, it only occurs
when I run my entire test suite (units). If I only run a single test, it
works fine.  And the code works fine when I run my application on either
operating system.

It appears Active Record is trying to serialize the entire
TZInfo::DataTimezone object into the database column when my "user"
object is saved.   This results in a "Data too long for column error".

The time zone field is mapped as a string in the database.  I create a
time_zone object in my "user" model object as follows:

  def time_zone_object
    ::ActiveSupport::TimeZone[time_zone]
  end

The error message is:

ActiveRecord::StatementInvalid: Mysql::Error: #22001Data too long for
column 'time_zone' at row 1:  <snip>
!ruby/object:ActiveSupport::TimeZone \nname: Central Time (US &
Canada)\ntzinfo: !ruby/object:TZInfo::DataTimezone \n  info:
!ruby/object:TZInfo::DataTimezoneInfo \n    identifier:
America/Chicago\n    last_month: 11\n    last_year: 2050\n    offsets:
\n      :o4: &id005 !ruby/object:TZInfo::TimezoneOffsetInfo \n
abbreviation: :CWT\n        std_offset: 3600\n        utc_offset:
-21600\n        utc_total_ <and so on...>

Attached is the entire error message.  This is really strange and any
tips on a workaround would be greatly appreciated. Here is the unit test
code that is failing:

require File.dirname(__FILE__) + '/../test_helper'
require "active_support/values/time_zone"

class UserTest < Test::Unit::TestCase
  fixtures :users, :teams, :seasons, :countries

  def setup
    delete_all_users
    @usa = countries(:us)
    @central = ::ActiveSupport::TimeZone["Central Time (US & Canada)"]
  end

  def test_active?
    bob = User.new(:name => Name.new('bob', nil, 'smith'),
      :email => 'bob@erac.com',
      :password => 'secret',
      :password_confirmation => 'secret',
      :time_zone => @central,
      :country_flag => @usa)
    bob.admin = true
    bob.save!

    assert !bob.active?

    bob.teams << Team.new(:name => "bob's team", :season =>
Season.current)
    bob.save!
    assert bob.active?
  end

Anyone ever seen anything like this before?  Thanks!
81b61875e41eaa58887543635d556fca?d=identicon&s=25 Frederick Cheung (Guest)
on 2008-11-15 18:26
(Received via mailing list)
On 15 Nov 2008, at 05:47, John Hohlen wrote:

> operating system.
>  end
>
If the time_zone attribute is supposed to be a name like "Central Time
(US & Canada)" shouldn't you be trying to set it to such a string
rather than trying to set it to the actual TimeZone instance?

Fred
1cf29a73259983fed1fe3f8acb0819a2?d=identicon&s=25 John Hohlen (hohlen)
on 2008-11-15 23:26
Hi Frederick,

That makes a lot more sense and that's what I've done.  I think I was
expecting too much magic out of Active Record / Rails.  I'm still
getting up to speed on this time zone stuff.  I'm not sure why the prior
approach ever worked at all (on my Mac).  There are times where I still
need an actual TimeZone object, so I've added the following method to my
User class.

  def time_zone_object
    ::ActiveSupport::TimeZone[time_zone]
  end

And the following if I need to format a time based on the user's time
zone.

  def tz_strftime(format, time)
    time_zone_object.tzinfo.strftime(format, time)
  end

Problem solved.  Thanks again for the help.
This topic is locked and can not be replied to.