Установка default_timezone для одной модели

У меня проблема с чтением из базы данных, которая подается из другой системы, так как я просто могу читать из нее, и дата и время хранятся в: локальном часовом поясе.

Как и в случае с приложениями Rails 3.2, он «должен» храниться в :utc, как и все другие мои таблицы в этом приложении.

Мне нужно, чтобы только эта модель была в :local. Остальные должны быть в :utc

Мой местный часовой пояс: «UTC-04:00».

class ExternalTable < ActiveRecord::Base
  establish_connection :otherdb
  table_name :iseries_table  <-- I have to live with it.
  default_timezone = :local
  puts "my default timezone is #{default_timezone}"

  #lot's of defs
   .....
end

Ходовые «рельсы с»

> ExternalTable.inspect
«lot´s of attributes»
my default timezone is :utc  <---utc!?. I have just set it to :local!?!?!?

> ExternalTable.default_timezone 
:utc

> ExternalTable.default_timezone = :local
:local

> ExternalTable.default_timezone 
:local  <--- yeah, right. Setting it AFTER instantiated, works.

Таким образом, кажется, что Rails устанавливает для всех часовых поясов ActiveRecord.Base обратно значение :utc после его инициализации, переопределяя значение ActiveRecord по умолчанию, то есть :local.

Есть много способов обойти это, например, установить before_filter на каждом контроллере, но это просто не похоже на Rubyist.


person Carlos Troncoso    schedule 16.02.2012    source источник
comment
У меня такая же проблема, только наоборот - нужна только одна модель :utc   -  person Gabe Moothart    schedule 20.09.2013
comment
Сложность заключается в том, что default_timezone является атрибутом класса. Установите его на одну модель, и он будет применяться и к другим вашим моделям.   -  person Gabe Moothart    schedule 20.09.2013


Ответы (2)


Разве не должно быть:

self.default_timezone = :local

В противном случае вы создаете локальную переменную с именем «default_timezone».

Если вы просто хотите, чтобы он применялся к одному классу, вы можете создать одноэлементный метод:

class ExternalTable < ActiveRecord::Base
  def self.default_timezone
    :local
  end
end

Немного хакерский, но должен работать.

person Eric Anderson    schedule 05.04.2012
comment
Это правильно, но это не делает то, что он хочет. Проблема в том, что default_timezone является атрибутом класса, поэтому он будет применяться ко всем моделям ActiveRecord, а не только к той, для которой он его устанавливает. - person Gabe Moothart; 20.09.2013
comment
Согласен с первым примером. Но во втором примере это класс ExternalTable. Таким образом, переменные класса должны влиять только на таблицы этого конкретного класса. Верно? - person Richard_G; 21.09.2013
comment
Зависит от того, как определен default_timezone. Rails использует cattr_accessor(apidock.com/rails/Class/cattr_accessor). Это общее значение для всех подклассов родительского класса. Измените его где угодно, и он изменится для всех. Если бы они использовали class_attribute(apidock.com/rails/Class/class_attribute), то он вел бы себя как вы описываете. Но они этого не сделали. Поэтому вместо этого мой пример просто исправляет default_timezone только для подкласса, чтобы предоставить совершенно новое определение, которое просто возвращает жестко закодированное значение. - person Eric Anderson; 23.09.2013
comment
На самом деле это не работает, ActiveRecord жестко кодирует Base.default_timezone в нескольких местах. Все еще хорошо для награды, если это окажется на самом деле невозможным. - person Gabe Moothart; 24.09.2013
comment
Меня это не удивляет. Возможно, поэтому он использовал cattr_accessor вместо class_attribute. Вы можете отправить патч, который удаляет жесткие коды, но в любом случае могут быть странные пограничные случаи с использованием моделей в разных часовых поясах, поэтому оно того не стоит. - person Eric Anderson; 25.09.2013
comment
это ужасно, и должен быть способ. :( Я имею дело с подключением к устаревшей базе данных, которая требует, чтобы я добавлял время по местному времени, но моя база данных rails все хороша и UTC. Rails должен предоставить простой способ переопределить время для определенного поля в конкретной модели. - person don.najd; 22.05.2019
comment
@don.najd, вы все еще ищете решение для этого? - person 244an; 09.08.2020

В Rails 6 вы уже можете написать свой вопрос, который установит для каждого класса, унаследованного от BiLocalTimeRecord, datetime как локальное время:

    module Bi
      class BiLocalTimeRecord < ActiveRecord::Base
        self.abstract_class = true
        self.default_timezone = :local
        establish_connection :cybros_bi
      end
    end
person Eric Guo    schedule 09.08.2019