Добавить метки времени в существующую таблицу - PullRequest
156 голосов
/ 25 сентября 2011

Мне нужно добавить метки времени (created_at & updated_at) к существующей таблице. Я попробовал следующий код, но он не работал.

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

Ответы [ 15 ]

194 голосов
/ 25 сентября 2011

Помощник отметки времени доступен только в блоке create_table.Вы можете добавить эти столбцы, указав типы столбцов вручную:

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 все равно будет обрабатывать эти столбцы как столбцы меток времении обновите значения в обычном режиме.

85 голосов
/ 25 сентября 2011

Миграции - это всего лишь два метода класса (или методы экземпляра в 3.1): up и down (а иногда и change метод экземпляра в 3.1).Вы хотите, чтобы ваши изменения вошли в метод 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 (спасибо Дейву):

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

Возможно, вы вводите в заблуждение def change, def change_table и change_table.

Подробнее см. В руководстве по миграции .

70 голосов
/ 30 сентября 2012

Ваш исходный код очень близок к правильному, вам просто нужно использовать другое имя метода.Если вы используете Rails 3.1 или новее, вам нужно определить метод change вместо change_table:

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

Если вы используете более старую версию, вам нужно определить up иdown методов вместо change_table:

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

  def down
    remove_timestamps(:users)
  end
end
39 голосов
/ 21 апреля 2017
Ответ

@ user1899434 о том, что «существующая» таблица здесь может означать таблицу с уже имеющимися записями, записи, которые вы, возможно, не хотите удалять.Поэтому, когда вы добавляете временные метки со значением null: false, которое является значением по умолчанию и часто желательно, все существующие записи являются недействительными.

Но я думаю, что ответ можно улучшить, объединяя два этапа в одну миграцию,а также с использованием более семантического метода add_timestamps:

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

Вы можете заменить некоторую другую временную метку на DateTime.now, например, если вы хотите вместо этого создавать / обновлять существующие записи на заре времени.

37 голосов
/ 25 сентября 2011
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

8 голосов
/ 06 марта 2017
def change
  add_timestamps :table_name
end
6 голосов
/ 13 сентября 2018

Ник Дэвис ответ является наиболее полным с точки зрения добавления столбцов меток времени в таблицу с существующими данными. Единственным недостатком является то, что он повысит ActiveRecord::IrreversibleMigration на db:rollback.

Это должно быть изменено так, чтобы работать в обоих направлениях:

def change
  add_timestamps :campaigns, default: DateTime.now
  change_column_default :campaigns, :created_at, from: DateTime.now, to: nil
  change_column_default :campaigns, :updated_at, from: DateTime.now, to: nil
end
2 голосов
/ 15 ноября 2018

не уверен, когда именно это было введено, но в rails 5.2.1 вы можете сделать это:

class AddTimestampsToMyTable < ActiveRecord::Migration[5.2]
  def change
    add_timestamps :my_table
  end
end

для получения дополнительной информации см. « с использованием метода изменения » в документах по миграции активных записей.

2 голосов
/ 14 июня 2018

add_timestamps (имя_таблицы, options = {}) public

Добавляет столбцы меток времени (созданный_и обновленный_кат) в имя_таблицы.Дополнительные параметры (например, null: false) пересылаются в # add_column.

class AddTimestampsToUsers < ActiveRecord::Migration
  def change
    add_timestamps(:users, null: false)
  end
end
2 голосов
/ 21 августа 2012

Я сделал простую функцию, которую вы можете вызвать, чтобы добавить в каждую таблицу (при условии, что у вас есть существующая база данных) поля creation_at и updated_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
...