Как вернуть дату (а не TimeWithZone) из столбца даты Oracle в ActiveRecord?

Среда: Rails 2.2.2, Oracle 10g

Большинство столбцов, объявленных "date" в моих моделях 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

работает отлично. Но этого я пытаюсь избежать. Я попросил АР назначить мне свидание, я хочу свидание еще раз.

И я мог бы добавить в свой класс метод effective_date_as_date - он тоже работает. Но, конечно, не невозможно просто устроить свидание, дагнаббит.

ПРЕДВАРИТЕЛЬНОЕ ОБНОВЛЕНИЕ

В конце концов я понял, почему это была особая проблема с Oracle: нет различия между DATE и DATETIME, поэтому ActiveRecord не может без посторонней помощи определить, означает ли нулевое время полночь (возможно, с поправками часового пояса) или только дату. Ба. Глупый оракул. Так что мне придется либо пойти по пути плагина, либо изменить мою базу данных (заманчиво, очень заманчиво), либо продолжить беспорядок to_date / to_time, который у меня есть в настоящее время.

На самом деле это не ответ (и поэтому я просто оставляю это в качестве комментария!), Но я хотел бы отметить, что ORM DataMapper поддерживает этот случай, требуя, чтобы все свойства были объявлены (с типами) в модели.

Greg Campbell 30.09.2009 01:49
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
3 413
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы пробовали преобразовать свой атрибут в тип даты?

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

да. И фу. На самом деле, черт возьми. Я специально пытаюсь избежать написания to_date во всем моем коде. СУХОЙ и все такое ... Я мог бы переопределить аксессуар в моих моделях, где это необходимо, но снова фу.

Mike Woodhouse 08.12.2008 18:37

Какую базу данных вы используете? Возможно, тип столбца, с которым сопоставляется объект Date, не соответствует тому, что вы думаете в своей базе данных. Очень сомнительно, но возможно.

mwilliams 08.12.2008 18:56

Oracle: это столбец DATE, который также может принимать значение времени. Кажется, я чрезмерно страдаю от даты и времени независимо от БД, что заставляет меня думать, что я чего-то упускаю ... :)

Mike Woodhouse 08.12.2008 19:01

Вы пробовали Enhanced Oracle Adapter for ActiveRecord? Раньше я использовал Rails с Oracle, и это интересное сочетание. Похоже, это может решить вашу проблему! См. Мой ответ по ссылке.

mwilliams 08.12.2008 19:09

Месяцы спустя: я использую усовершенствованный Oracle, и мне это нравится.

Mike Woodhouse 30.09.2009 12:02

Я обнаружил ошибку: нельзя сравнивать TimWithZone с Date. «Сравнение неуместно, - говорит мне Рубин.

Вы абсолютно правы: вот почему происходит вся эта ужасная ерунда to_date / to_time. Я просто не могу поверить, что я единственный, кто чувствует боль, и не похоже, чтобы она не была устранена. Но, возможно, я ошибаюсь.

Mike Woodhouse 13.01.2009 18:06

Другие вопросы по теме