【问题标题】:Setting default_timezone on a single model在单个模型上设置 default_timezone
【发布时间】:2012-03-08 00:08:18
【问题描述】:

我从其他系统提供的数据库读取时遇到问题,因为我只能从中读取,并且日期时间存储在 :local 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

运行“rails c”

> 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。

【问题讨论】:

  • 我有同样的问题,只是反过来 - 只需要一个模型:utc
  • 难点在于 default_timezone 是class attribute。将其设置在一个模型上,它也适用于您的其他模型。

标签: ruby-on-rails ruby-on-rails-3 timezone rails-activerecord utc


【解决方案1】:

不应该是:

self.default_timezone = :local

否则,您将创建一个名为“default_timezone”的局部变量。

如果您只想将其应用于一个类,您可以创建一个单例方法:

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

有点hackish,但应该可以。

【讨论】:

  • 这是对的,但它并没有达到他想要的效果。问题是 default_timezone 是一个类属性,因此它将适用于所有 ActiveRecord 模型,而不仅仅是他设置的那个。
  • 同意第一个例子。但是,在第二个示例中,该类是 ExternalTable。因此,类变量应该只影响该特定类的表。对吗?
  • 取决于 default_timezone 的定义方式。 Rails 使用 cattr_accessor(apidock.com/rails/Class/cattr_accessor)。这是父类的所有子类之间的共享值。在任何地方更改它,它会为每个人而改变。如果他们使用了 class_attribute(apidock.com/rails/Class/class_attribute) 那么它的行为就像你描述的那样。但他们没有。因此,我的示例只是在子类上对 default_timezone 进行猴子补丁,以提供一个全新的定义,该定义只返回一个硬编码的值。
  • 这实际上似乎不起作用,ActiveRecord 在几个地方硬编码 Base.default_timezone。如果事实证明实际上是不可能的,那么对于赏金仍然有好处。
  • 我并不感到惊讶。可能是它使用 cattr_accessor 而不是 class_attribute 的原因。您可以提交删除硬代码的补丁,但是在不同时区使用模型可能会出现奇怪的边缘情况,因此可能不值得。
【解决方案2】:

在 Rails 6 中,你已经可以写成你的问题了,这会将继承自 BiLocalTimeRecord 的每个类设置为本地时间:

    module Bi
      class BiLocalTimeRecord < ActiveRecord::Base
        self.abstract_class = true
        self.default_timezone = :local
        establish_connection :cybros_bi
      end
    end

【讨论】:

    猜你喜欢
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多