如何从ActiveRecord中的Oracle日期列返回Date(而不是TimeWithZone)?

时间:2008-12-08 15:23:07

标签: ruby-on-rails oracle datetime activerecord

环境: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 s?

更新:更多抱怨...

是的,我可以使用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混乱。

2 个答案:

答案 0 :(得分:1)

您是否尝试将属性转换为日期类型?

API描述to_date如下:

  

将self转换为Ruby Date对象;   时间部分被丢弃

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

<强>更新

Enhanced Oracle Adapter

看起来这个适配器可能已解决您的问题......

  

设置下面的选项,结果   名称中包含DATE的列   被模仿为日期(而不是时间   这是DATE列的默认值   数据库)

ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true

答案 1 :(得分:1)

我发现了一个错误:你无法将TimWithZone与Date进行比较。比较失败,红宝石告诉我。