复制db表列并更改其类型

时间:2014-07-16 20:07:17

标签: ruby-on-rails activerecord

我有一张表格如下:

create_table "google_records", :force => true do |t|
 t.string   "user_id"
 t.string   "date"
 t.text     "stats"
 t.text     "account_name"
 t.datetime "created_at",                                       :null => false
 t.datetime "updated_at",                                       :null => false
 t.float    "total_cost",        :limit => 12, :default => 0.0, :null => false
 t.integer  "total_conversions",               :default => 0,   :null => false
end

我需要能够使用group('year(date)').group('month(date)')之类的组来查询数据库,但不能这样做,因为我的列类型是日期的字符串。

不是通过迁移将列类型更改为datetime(因为prod上有很多代码将它用作字符串),我考虑添加一个新列。

有没有办法通过复制当前日期列然后在每个字段上调用类似date.to_datetime的内容来填充该新列?

有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

是的,没有理由为什么你不能创建一个字段,并且(在迁移本身中)放入一些Ruby代码来解决这个问题' up'迁移

reversible do |dir|
  dir.up { GoogleRecord.update_all_dates }
end

并在类中定义:update_all_dates来做到这一点。

您可能还想在模型中添加before_save回调,以便每次保存记录时,new_date都会使用date

中的值进行更新
class GoogleRecord < ActiveRecord::Base
before_save :update_date

def self.update_all_dates
  all.each {|gr| gr.update_attribute(:new_date, Date.parse(gr.date)) }
end

private
def update_date
  self.new_date = Date.parse(date)
end

答案 1 :(得分:0)

strptime允许您提供格式和字符串,它会为您输出日期时间。

因此,创建新的datetime列(在我的示例中为:datetime_column),然后在rails控制台中

> all_records = GoogleRecord.all
> all_records.each {|r| r.update_attributes(datetime_column: Date.sprptime(r.date, "%Y-%m-%d"}
(or whatever your date format is in)

你可能不得不使用它,因为我没有运行任何测试用例,但如果有任何问题请告诉我