我使用Rails的常见用例(对我来说)是使用自定义查询,比如这个简化的
> User.select("NOW() as now").first.now
User Load (0.9ms) SELECT NOW() as now FROM "users" ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> 2016-02-21 04:22:04 UTC
这里的问题是,时区与我在模型上使用预定义列的方式不同,例如created_at
。
> User.first.created_at
User Load (5.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> Wed, 20 Mar 2013 02:13:27 CET +01:00
这是另一个。这是一个更复杂的例子,它只是再次获取created_at
coumn,但是在子查询中。
user = User.select(%q{
(
SELECT created_at
FROM users u
WHERE u.id = users.id
LIMIT 1
) as custom_created_at, created_at
}).first
user.custom_created_at.strftime("%F %H:%M") # => "2013-03-20 01:13"
user.created_at.strftime("%F %H:%M") # => "2013-03-20 02:13"
我尝试过全局设置时区,就像这样
config.time_zone = "Stockholm"
config.default_timezone = :local
但它只适用于预定义列,例如created_at
。
请注意,我可以使用Time#in_time_zone
手动设置时区对象的时区,如下所示
> User.select("NOW() as now").first.now.in_time_zone("Stockholm")
User Load (1.5ms) SELECT NOW() as now FROM "users" ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> Sun, 21 Feb 2016 05:25:01 CET +01:00
但我不想手动对所有查询进行此操作。关于如何解决这个问题的任何想法?
这个特殊项目使用的是Ruby 2.2.2和Rails 5 beta 2,但我想说它适用于Rails 3之上的所有版本。
答案 0 :(得分:1)
如何设置
config.active_record.default_timezone = 'xxxxxx'
在application.rb
?
答案 1 :(得分:1)
@Hassan的答案暂时正常,但正如@Harfangk在上面的评论中所提到的,这也改变了存储在数据库中的所有现有日期列。这在我的应用程序中引起了很多问题,其中一个是使用回形针上传的所有图片都停止工作(因为路径是使用neo4j start
列计算的)。
所以我最后编写了自己的关注点,它暴露了一个API,让你定义应该手动转换的列。
有一个用例示例。
created_at
这是实施。它使用class User < ApplicationRecord
include TimeZoneColumns
timezone_columns :custom_created_at
end
user = User.select(%q{
(
SELECT created_at
FROM users u
WHERE u.id = users.id
LIMIT 1
) as custom_created_at, created_at
}).first
user.custom_created_at.strftime("%F %H:%M") # => "2013-03-20 01:13" OK
user.created_at.strftime("%F %H:%M") # => "2013-03-20 01:13" OK
并在您的环境中设置Time#in_time_zone
。我的测试支持逻辑。
config.time_zone