我有一个名为subs
的表,其中有许多articles
。 articles
表有一个名为published
的时间戳列。
Sub.select( "subs.*,MAX(articles.published) published").joins("LEFT OUTER JOIN articles ON subs.id=articles.sub_id").group("subs.id").first.published.class
=> String
Article.select("max(published) published").group("id").first.published.class
=> ActiveSupport::TimeWithZone
我想从第一个查询中获取一个ActiveSupport::TimeWithZone
对象。
答案 0 :(得分:0)
Rails 3
Rails确定如何根据数据库列定义键入强制转换属性。例如,假设您的created_at
模型上有Sub
方法。加载记录时read_attribute
被使用(ActiveRecord::AttributeMethods::Read)。这使用type_cast_attribute
来确定如何根据列信息转换值。例如,如果您使用的是PostgreSQL,则可以使用:
Sub.columns.detect { |c| c.name == "created_at" }.type_cast_code("v")
=> "ActiveRecord::ConnectionAdapters::PostgreSQLColumn.string_to_time(v)"
但是Rails不知道如何处理Sub
模型上没有的列。所以它只返回String
。如果需要使用ActiveSupport::TimeWithZone
对象,可以使用以下命令转换值:
published = Sub.select( "subs.*,MAX(articles.published) published").joins("LEFT OUTER JOIN articles ON subs.id=articles.sub_id").group("subs.id").first.published
published.present? ? Time.zone.parse(published) : nil
Rails 4
在Rails 4中,Rails对于这种类型转换更为智能。执行SQL时,会创建ActiveRecord::Result
并将column_types
传递给初始化程序。在您的示例Sub.select
查询中,published
列将被投射为Time
对象。