English 中文(简体)
如何从ActiveRecord中的Oracle日期列返回日期(而不是TimeWithZone)?
原标题:
  • 时间:2008-12-08 15:23:07
  •  标签:

环境:Rails 2.2.2,Oracle 10g

我的ActiveRecord模型中大多数声明为“日期”(date)的列确实是日期:它们根本不关心时间。

因此,使用如下声明的模型:#

class MyDateOnlyModel < ActiveRecord::Migration
  def self.up
    create_table :my_date_only_model do |t|
      t.date :effective_date
      t.timestamps
    end
  end
end

类似于这样的测试写作:

test_date = Date.new(2008,12,05)
MyDateOnlyModel.create!(:effective_date => test_date)
assert_equal test_date, MyDateOnlyModel.find(:first).effective_date

应该通过,不是吗?(假设我没有在转录上弄错任何东西)

但这并不是完全的。我得到了这个:

<Fri, 05 Dec 2008> expected but was
<Fri, 05 Dec 2008 00:00:00 UTC +00:00>.

那么我将日期放入数据库中,得到了什么……那么我得到了什么?

puts MyDateOnlyModel.find(:first).eff_date.class

告诉我实际上我得到了一个 ActiveSupport::TimeWithZone,这根本不是我想要的。

有没有一个简单的方法告诉ActiveRecord有些(而不是全部)列是Date,并且只是Date?

更新:更多抱怨...

是的,我可以使用to_date函数:

assert_equal test_date, MyDateOnlyModel.find(:first).effective_date.to_date

运作得很好。但那正是我想避免的。我要求 AR 给我安排一个约会,我希望得到一个约会。

我可以给我的类添加一个方法,effective_date_as_date - 这也可以工作。但是肯定不可能只是得到一个日期,dagnabbit。

预先接受更新

最终我意识到为什么这是一个Oracle的特殊问题:DATE和DATETIME之间没有区别,因此ActiveRecord无法自行确定时间零是否表示午夜(可能需要时区校正)或仅表示日期。糟糕。愚蠢的Oracle。所以我要么选择使用插件,改变我的数据库(很有诱惑力),或者继续使用目前混乱的to_date/to_time方法。

最佳回答

你尝试将你的属性转换为日期类型了吗?

API中描述to_date如下:

Converts self to a Ruby Date object; time portion is discarded

test_date = Date.new(2008,12,05)
MyDateOnlyModel.create!(:effective_date => test_date)
assert_equal test_date, MyDateOnlyModel.find(:first).effective_date.to_date

更新

增强型Oracle适配器

看起来这个适配器可能有解决你的问题的方法...

Set the option below and as a result columns with DATE in their name will be emulated as Date (and not as Time which is default for DATE columns in database)

ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
问题回答

我发现了一个bug:你不能将TimWithZone与Date进行比较。比较失败,Ruby告诉我。





相关问题
热门标签