来自连接表的Rails 3 + Postgres + JSON时间戳列未调用ActiveSupport :: TimeWithZone.as_json

时间:2012-10-27 04:35:12

标签: ruby-on-rails json postgresql activerecord

我已根据两个表发送Rails AREL查询结果的json响应。响应包括两个时间戳列:updated_at和updated_at_table_2。我重写ActiveSupport :: TimeWithZone.as_json方法以获取JSON所需的日期时间格式。

显示了相同的方法
http://stackoverflow.com/questions/2937740/rails-dates-with-json

我目前的JSON响应是: {          “updated_at”:“10/26/2012 22:04:07 -0400”,          “updated_at_table_2”:“2012-10-27 02:04:07.463015” }

我希望他们是一样的。我依赖Rails代码生成json。

render :json => { :customer_order  =>  @customer_order  }

其中@custoemr_order派生自:

CustomerOrder.select(%Q[
      updated_at,
      c.updated_at as updated_at_table_2
    ] ).
    joins( %{ as co inner join customers as c on (co.customer_id = c.id)

问题:我如何告诉Rails 3以与update_at列相同的方式处理as_json和update_at列?

任何建议/指针都很棒。

注意:如果没有好的解决方案,我发现这篇文章询问了同样的根问题(虽然不是关于json)。 :

http://stackoverflow.com/questions/12067173/rails-postgres-not-returning-timezone-info-on-column-from-joined-table

1 个答案:

答案 0 :(得分:1)

如果你看看你的查询给你什么,你会看到你出错的确切位置:

 > o = CustomerOrder.select(%Q[ ... ]).joins(...)
 > puts o.updated_at.class
=> ActiveSupport::TimeWithZone
 > puts o.updated_at_table_2.class
=> String

ActiveRecord无法知道updated_at_table_2应该是什么类型的东西,所以它将它保留为字符串,而to_json猴子补丁不会应用于字符串。

如果你想继续使用你的to_json猴子补丁(我认为这是一个坏主意),那么你需要手动将updated_at_table_2转换为ActiveSupport::TimeWithZone,如下所示:

x = ActiveSupport::TimeWithZone.new(
    Time.parse(o.updated_at_table_2),
    Time.zone
)
# x is now an ActiveSupport::TimeWithZone

或者,您可以加载关联的对象并在其上调用updated_at

我废弃了整个方法:让服务器专门以UTC工作,以ISO-8601格式发送客户端时间戳,让客户处理应用本地时区。