Add timestamps to an existing table

2019-01-21 01:48发布

I need to add timestamps (created_at updated_at) to an existing table. I tried the following code but it didn't work. I have also tried other solutions I found online but they don't work either.

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

How can I do it?

14条回答
萌系小妹纸
2楼-- · 2019-01-21 02:30

@user1899434's response picked up on the fact that an "existing" table here could mean a table with records already in it, records that you might not want to drop. So when you add timestamps with null: false, which is the default and often desirable, those existing records are all invalid.

But I think that answer can be improved upon, by combining the two steps into one migration, as well as using the more semantic add_timestamps method:

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

You could substitute some other timestamp for DateTime.now, like if you wanted preexisting records to be created/updated at the dawn of time instead.

查看更多
可以哭但决不认输i
3楼-- · 2019-01-21 02:31
def change
  add_timestamps :table_name
end
查看更多
爱情/是我丢掉的垃圾
4楼-- · 2019-01-21 02:33

Migrations are just two class methods (or instance methods in 3.1): up and down (and sometimes a change instance method in 3.1). You want your changes to go into the up method:

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

If you're in 3.1 then you could also use change (thanks Dave):

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

Perhaps you're confusing def change, def change_table, and change_table.

See the migration guide for further details.

查看更多
劫难
5楼-- · 2019-01-21 02:35

The timestamp helper is only available in the create_table block. You can add these columns by specifying the column types manually:

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

While this does not have the same terse syntax as the add_timestamps method you have specified above, Rails will still treat these columns as timestamp columns, and update the values normally.

查看更多
来,给爷笑一个
6楼-- · 2019-01-21 02:36
class AddTimestampsToUser < ActiveRecord::Migration
  def change
    change_table :users do |t|
      t.timestamps
    end
  end
end

Available transformations are

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

查看更多
做个烂人
7楼-- · 2019-01-21 02:36

I personally used the following, and it updated all previous records with the current time/date:

add_column :<table>, :created_at, :datetime, default: Time.zone.now, null: false
add_column :<table>, :updated_at, :datetime, default: Time.zone.now, null: false
查看更多
登录 后发表回答