将时间戳添加到现有的表

我需要添加时间戳(created_at updated_at)到一个现有的表。 我试过下面的代码,但没有奏效。 我也试过了我在网上find的其他解决scheme,但是他们也不pipe用。

class AddTimestampsToUser < ActiveRecord::Migration def change_table add_timestamps(:users) end end 

我该怎么做?

时间戳帮助程序仅在create_table块中可用。 您可以通过手动指定列types来添加这些列:

 class AddTimestampsToUser < ActiveRecord::Migration def change_table add_column :users, :created_at, :datetime, null: false add_column :users, :updated_at, :datetime, null: false end end 

虽然这与上面指定的add_timestamps方法没有相同的简洁语法,但Rails仍将这些列作为时间戳列,并正常更新值。

迁移只是两个类方法(3.1中的实例方法): updown (有时是3.1中的change实例方法)。 你希望你的改变进入up方法:

 class AddTimestampsToUser < ActiveRecord::Migration def self.up # Or `def up` in 3.1 change_table :users do |t| t.timestamps end end def self.down # Or `def down` in 3.1 remove_column :users, :created_at remove_column :users, :updated_at end end 

如果你在3.1,那么你也可以使用change (感谢Dave):

 class AddTimestampsToUser < ActiveRecord::Migration def change change_table(:users) { |t| t.timestamps } end end 

也许你会困惑def changedef change_tablechange_table

有关详细信息,请参阅迁移指南 。

您的原始代码非常接近,您只需要使用不同的方法名称。 如果您使用Rails 3.1或更高版本,则需要定义change方法而不是change_table

 class AddTimestampsToUser < ActiveRecord::Migration def change add_timestamps(:users) end end 

如果您使用的是旧版本,则需要定义down方法而不是change_table

 class AddTimestampsToUser < ActiveRecord::Migration def up add_timestamps(:users) end def down remove_timestamps(:users) end end 
 class AddTimestampsToUser < ActiveRecord::Migration def change change_table :users do |t| t.timestamps end end end 

可用的转换是

 change_table :table do |t| t.column t.index t.timestamps t.change t.change_default t.rename t.references t.belongs_to t.string t.text t.integer t.float t.decimal t.datetime t.timestamp t.time t.date t.binary t.boolean t.remove t.remove_references t.remove_belongs_to t.remove_index t.remove_timestamps end 

http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html

@ user1899434的回答是这样的:“现有”表在这里可能意味着一个已经有logging的表,这个logging你可能不想删除。 因此,当您添加时间戳为null:false(默认且通常是可取的)时,这些现有logging都是无效的。

但是我认为,通过将两个步骤结合到一个迁移中,以及使用更多的语义add_timestamps方法,可以改进答案:

 def change add_timestamps :projects, default: DateTime.now change_column_default :projects, :created_at, nil change_column_default :projects, :updated_at, nil end 

你可以用一些其他的时间戳来代替DateTime.now ,就好像你希望预先存在的logging在时间黎明时被创build/更新。

 def change add_timestamps :table_name end 

我做了一个简单的函数,您可以调用它来添加到每个表(假设您有一个现有的数据库) created_atupdated_at字段:

  # add created_at and updated_at to each table found. def add_datetime tables = ActiveRecord::Base.connection.tables tables.each do |t| ActiveRecord::Base.connection.add_timestamps t end end 

对于那些不使用Rails但是使用activerecord的人来说,下面的代码还会将一列添加到现有模型中,例如整数字段。

 ActiveRecord::Schema.define do change_table 'MYTABLE' do |table| add_column(:mytable, :my_field_name, :integer) end end 

以前的答案似乎是正确的,但是如果我的表已经有条目我遇到了问题。

我会得到'错误:列'created_at“包含空值'。

为了解决,我用:

 def up add_column :projects, :created_at, :datetime, default: nil, null: false add_column :projects, :updated_at, :datetime, default: nil, null: false end 

然后,我使用gem migration_data为迁移中的当前项目添加时间,例如:

 def data Project.update_all created_at: Time.now end 

然后在此迁移后创build的所有项目都将被正确更新。 确保服务器也重新启动,以便Rails ActiveRecord开始跟踪logging上的时间戳。

我个人使用了以下内容,并使用当前时间/date更新了以前的所有logging:

 add_column :<table>, :created_at, :datetime, default: Time.zone.now, null: false add_column :<table>, :updated_at, :datetime, default: Time.zone.now, null: false