Rails не конвертирует часовой пояс (PostgreSQL) - PullRequest
6 голосов
/ 21 апреля 2011

У меня проблема с часовыми поясами и базой данных postgresql (Rails 3.0.4, PostgreSQL 9.0). Я использую пользовательскую область, в которой я добавляю некоторые условия, делаю соединения и т.д.pp.

Проблема в том, что Rails не конвертирует время в мой местный часовой пояс. Вот код области:

  scope :with_activities_within_range_in_week, lambda{ |latMin, lngMin, latMax, lngMax, date|
    select("date_trunc('day', activities.starting_at) as date,
      count(activities.id) as value
    ") \
    .within(latMin, lngMin, latMax, lngMax) \
    .joins(:activities) \
    .merge(Activity.in_week(date)) \
    .group("date") \
    .order("date")
  }

Внутренний метод проверяет диапазоны, область действия Activity.in_week возвращает это:

where("activities.starting_at >= ? AND activities.starting_at < ?", start, stop)

И в операторе select я хочу обрезать поле initial_at до дня.

Я получаю следующий вывод для поля даты:

2011-04-07 18:48:32
2011-04-02 14:07:20
2011-04-02 14:06:49

К сожалению, он не включает часовой пояс. Когда я пытаюсь получить доступ к моей модели через «обычные» функции Rails, она работает:

puts Activity.first.starting_at
-> 2011-04-15 06:47:55 +0200

Что я делаю не так? Надеюсь, что кто-то может помочь!

ТНХ, пингвин

1 Ответ

5 голосов
/ 21 апреля 2011

В вашей базе данных хранятся ваши метки времени в формате UTC (как и должно быть).ActiveRecord выполняет настройку часового пояса, когда знает, что у него есть временная метка;поэтому, когда вы говорите следующее:

puts Activity.first.starting_at

AR знает, что starting_at является временной меткой, поэтому она создает метку времени как экземпляр ActiveSupport::TimeWithZone, и этот класс применяет настройку часового пояса.Но когда вы говорите следующее:

select("date_trunc('day', activities.starting_at) as date ...

AR не собирается анализировать SQL, чтобы выяснить, что date_trunc вернет метку времени, AR даже не знает, что означает date_trunc.AR просто увидит строку, выходящую из базы данных, и передаст ее вам без интерпретации.Вы можете сами передать эту строку ActiveSupport::TimeWithZone (или вашему любимому классу обработки времени): нет ничего плохого в том, чтобы сообщать вещам AR то, что он не знает и не может знать сам по себе.

Rails умный, но онне волшебство.

...