How to return date (not TimeWithZone) from Oracle date column in ActiveRecord?
Environment: Rails 2.2.2, Oracle 10g
Most of the columns declared as "date" in my ActiveRecord models are exactly that: dates: they don't care about time at all.
So with the model declared: #
class MyDateOnlyModel < ActiveRecord::Migration
def self.up
create_table :my_date_only_model do |t|
t.date :effective_date
t.timestamps
end
end
end
by writing a test like this:
test_date = Date.new(2008,12,05)
MyDateOnlyModel.create!(:effective_date => test_date)
assert_equal test_date, MyDateOnlyModel.find(:first).effective_date
gotta get through, right? (Assuming I haven't messed up anything by deciphering the above, of course)
But this is not so - not really. I get the following:
<Fri, 05 Dec 2008> expected but was
<Fri, 05 Dec 2008 00:00:00 UTC +00:00>.
So, I put the date in the database and got ... well, what did I get?
puts MyDateOnlyModel.find(:first).eff_date.class
tells me what I really have ActiveSupport::TimeWithZone
. This was not at all what I wanted.
Is there an easy way to tell ActiveRecord that some (not all) columns Date
and only Date
s?
UPDATE: more complaining ...
Yes, I could use to_date:
assert_equal test_date, MyDateOnlyModel.find(:first).effective_date.to_date
works great. But this is what I am trying to avoid. I asked AR to do me a date, I want the date back.
And I could add a method to my class, effective_date_as_date, which works too. But of course it is not possible to just get the date, dagnabbit.
ADDITIONAL UPDATE
Eventually I figured out why this was a particular problem with Oracle: the differences between DATE and DATETIME are not different, so ActiveRecord cannot figure out if a time at zero would mean midnight (possibly with timezone adjustments) or just a date, Bah. Silly Oracle. So I'll either have to go down the plugin, change my database (tempting, so very tempting), or continue with the to_date / to_time problem I currently have.
source to share
Have you tried applying your attribute to the Date type?
The API describes to_date as follows:
Converts itself to a Ruby Date object; the temporary part 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
Update
It looks like this adapter might have a problem with your problem ...
Set the parameter below and as a result columns with DATE in their name will be emulated as date (and not as time) which is used by default for DATE columns in the database)
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
source to share