2008-12-08 9 views
0

Environnement: Rails 2.2.2, Oracle 10gComment renvoyer une date (pas un TimeWithZone) à partir d'une colonne de date Oracle dans ActiveRecord?

La plupart des colonnes déclarées "date" dans mes modèles ActiveRecord sont exactement celles-ci: dates: elles ne se soucient absolument pas de l'heure.

Donc, avec un modèle ainsi déclaré: #

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

écrire un test comme celui-ci:

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

devrait passer, devrait-il pas? (En supposant que je n'ai rien gâché en transcrivant ce qui précède, bien sûr)

Mais ce n'est pas - pas tout à fait. Je reçois ceci:

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

Je mis une date dans la base de données et nous avons obtenu ... bien ce que ne-je obtenir?

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

me dit que j'ai effectivement obtenu un ActiveSupport::TimeWithZone. Ce qui n'était pas ce que je voulais du tout.

Existe-t-il un moyen simple de dire à ActiveRecord que certaines colonnes (pas toutes) sont Date s et seulement Date s?

MISE À JOUR: plus se plaindre ...

Oui, je pourrais utiliser to_date:

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

fonctionne très bien. Mais c'est ce que j'essaie d'éviter. J'ai demandé à AR de me faire un rendez-vous, je veux un rendez-vous.

Et je pourrais ajouter une méthode à ma classe, effective_date_as_date - qui fonctionne aussi. Mais il n'est sûrement pas impossible d'avoir une date, dagnabbit.

PRÉRÉCEPTION MISE À JOUR

Finalement, je compris pourquoi cela était un problème particulier avec Oracle: il n'y a pas de distinction entre DATE et DATETIME, donc ActiveRecord ne peut pas comprendre sans aide si un temps de zéro signifie minuit (éventuellement avec des corrections de fuseau horaire) ou juste la date. Bah. Oracle stupide. Donc, je vais devoir soit descendre le chemin du plugin, changer ma base de données (tentant, donc très tentant) ou continuer avec le to_date/to_time mess que j'ai actuellement.

+1

Ce n'est pas vraiment une réponse (et donc je fais juste un commentaire!), Mais je note que l'ORM de DataMapper supporte ce cas en exigeant que toutes les propriétés soient déclarées (avec les types) dans le modèle . –

Répondre

1

Avez-vous essayé de convertir votre attribut en type Date?

L'API décrit to_date comme suit:

Transforme l'auto à un objet Date Ruby; partie de temps est mis au rebut

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

Mise à jour:

Enhanced Oracle Adapter

Il semble que cet adaptateur pourrait avoir une solution pour votre problème ...

Régler la option ci-dessous et par conséquent colonnes avec D Mangèrent en leur nom sera faire des émules Date (et non comme temps qui est par défaut pour les colonnes DATE dans la base de données )

ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true 
+0

Oui. Et beurk. Vraiment, vraiment beurk. J'essaie spécifiquement d'éviter d'avoir à écrire to_date partout dans mon code. DRY et tout ça ... Je pourrais remplacer l'accesseur dans mes modèles si nécessaire, mais encore beurk. –

+0

Quelle base de données utilisez-vous? Il se peut que le type de colonne auquel un objet Date est mappé ne soit pas ce que vous pensez dans votre base de données. Très douteux, mais possible. – mwilliams

+0

Oracle: il s'agit d'une colonne DATE, qui peut également prendre une valeur de temps. Je semble souffrir indûment avec des dates et des heures quel que soit le DB, ce qui me fait penser qu'il me manque quelque chose ... :) –

1

J'ai découvert un bug: vous ne pouvez pas comparer TimWithZone avec une date . La comparaison échoue, me dit Ruby.

+0

Vous avez absolument raison: c'est pourquoi il y a tout ce truc horrible to_date/to_time qui se passe. Je n'arrive tout simplement pas à croire que je suis la seule à ressentir la douleur, et il semble peu probable qu'elle n'ait pas été abordée. Mais peut-être que j'ai tort. –

Questions connexes