Ich muss einer vorhandenen Tabelle Zeitstempel (created_at updated_at) hinzufügen. Ich habe den folgenden Code ausprobiert, aber er hat nicht funktioniert. Ich habe auch andere Lösungen ausprobiert, die ich online gefunden habe, aber sie funktionieren auch nicht.
class AddTimestampsToUser < ActiveRecord::Migration
def change_table
add_timestamps(:users)
end
end
Wie kann ich es tun?
Der Zeitstempel-Helfer ist nur im create_table
-Block verfügbar. Sie können diese Spalten hinzufügen, indem Sie die Spaltentypen manuell angeben:
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
Dies hat zwar nicht die gleiche knappe Syntax wie die oben angegebene add_timestamps
-Methode, aber Rails behandelt diese Spalten immer noch als Zeitstempelpalten und aktualisiert die Werte normal.
Migrationen sind nur zwei Klassenmethoden (oder Instanzmethoden in 3.1): up
und down
(und manchmal auch eine change
-Instanzmethode in 3.1). Sie möchten, dass Ihre Änderungen in die up
-Methode übernommen werden:
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
Wenn Sie in 3.1 sind, können Sie auch change
verwenden (danke Dave):
class AddTimestampsToUser < ActiveRecord::Migration
def change
change_table(:users) { |t| t.timestamps }
end
end
Möglicherweise sind Sie def change
, def change_table
und change_table
verwirrend.
Weitere Informationen finden Sie im migration guide .
Ihr ursprünglicher Code steht ganz rechts, Sie müssen nur einen anderen Methodennamen verwenden. Wenn Sie Rails 3.1 oder höher verwenden, müssen Sie anstelle von change_table
eine change
-Methode definieren:
class AddTimestampsToUser < ActiveRecord::Migration
def change
add_timestamps(:users)
end
end
Wenn Sie eine ältere Version verwenden, müssen Sie statt change_table
up
- und down
-Methoden definieren:
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
Verfügbare Transformationen sind
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
Die Antwort von @ user1899434 hat sich auf die Tatsache bezogen, dass eine "vorhandene" Tabelle hier eine Tabelle mit bereits vorhandenen Datensätzen bedeuten kann, Datensätze, die möglicherweise nicht gelöscht werden sollen. Wenn Sie also Zeitstempel mit null: false hinzufügen (Standardeinstellung und häufig erwünscht), sind alle vorhandenen Datensätze ungültig.
Ich denke jedoch, dass die Antwort durch die Kombination der beiden Schritte in einer Migration und die Verwendung der semantischeren Methode add_timestamps verbessert werden kann:
def change
add_timestamps :projects, default: Time.zone.now
change_column_default :projects, :created_at, nil
change_column_default :projects, :updated_at, nil
end
Sie können DateTime.now
durch einen anderen Zeitstempel ersetzen, z. B. wenn Sie möchten, dass bereits vorhandene Datensätze zu Beginn erstellt/aktualisiert werden.
def change
add_timestamps :table_name
end
Nick Davies Antwort ist die umfassendste in Bezug auf das Hinzufügen von Zeitstempelspalten zu einer Tabelle mit vorhandenen Daten. Der einzige Nachteil ist, dass es ActiveRecord::IrreversibleMigration
auf einen db:rollback
erhöht.
Es sollte so modifiziert werden, dass es in beide Richtungen funktioniert:
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
Ich habe eine einfache Funktion erstellt, die Sie aufrufen können, um zu each table (sofern Sie eine vorhandene Datenbank haben) die created_at und updated_at Felder hinzuzufügen:
# 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
add_timestamps (tabellenname, options = {}) public
Fügt Zeitstempel (created_at und updated_at) zu Tabellenname hinzu. Zusätzliche Optionen (wie null: false) werden an #add_column weitergeleitet.
class AddTimestampsToUsers < ActiveRecord::Migration
def change
add_timestamps(:users, null: false)
end
end
Viele Antworten hier, aber ich werde auch meine posten, weil keine der vorherigen wirklich für mich gearbeitet hat :)
Wie einige angemerkt haben, fügt #add_timestamps
leider die Einschränkung null: false
hinzu, die dazu führt, dass alte Zeilen ungültig werden, da diese Werte nicht ausgefüllt sind. Die meisten Antworten hier deuten darauf hin, dass wir einen Standardwert (Time.zone.now
) festgelegt haben, aber ich würde das nicht gerne tun, da diese Standardzeitstempel für alte Daten nicht korrekt sind. Ich sehe den Wert nicht darin, der Tabelle falsche Daten hinzuzufügen.
Meine Migration war also einfach:
class AddTimestampsToUser < ActiveRecord::Migration
def change_table
add_column :projects, :created_at, :datetime
add_column :projects, :updated_at, :datetime
end
end
Nein null: false
, keine weiteren Einschränkungen. Alte Zeilen behalten ihre Gültigkeit mit created_at
als NULL
und update_at
als NULL
(bis eine Aktualisierung der Zeile durchgeführt wird). In neuen Zeilen sind created_at
und updated_at
wie erwartet ausgefüllt.
Die Antworten davor scheinen richtig zu sein, aber ich hatte Probleme, wenn meine Tabelle bereits Einträge hat.
Ich würde 'ERROR: Spalte created_at
enthält null
Werte' erhalten.
Um das zu beheben, habe ich verwendet:
def up
add_column :projects, :created_at, :datetime, default: nil, null: false
add_column :projects, :updated_at, :datetime, default: nil, null: false
end
Ich habe dann mit gem migration_data die Zeit für aktuelle Projekte zur Migration hinzugefügt, wie:
def data
Project.update_all created_at: Time.now
end
Dann werden alle nach dieser Migration erstellten Projekte korrekt aktualisiert. Stellen Sie sicher, dass auch der Server neu gestartet wird, damit Rails ActiveRecord
die Zeitstempel im Datensatz verfolgt.
Es ist change
, nicht change_table
für Rails 4.2:
class AddTimestampsToUsers < ActiveRecord::Migration
def change
add_timestamps(:users)
end
end
sie wissen nicht genau, wann genau dies eingeführt wurde, aber in Rails 5.2.1 können Sie Folgendes tun:
class AddTimestampsToMyTable < ActiveRecord::Migration[5.2]
def change
add_timestamps :my_table
end
end
weitere Informationen finden Sie unter " mit der Änderungsmethode " in den aktiven Datensatzmigrationsdokumenten.
Für diejenigen, die Rails nicht verwenden, aber Activerecord verwenden, fügt das Folgende auch eine Spalte zu einem vorhandenen Modell hinzu. Beispiel ist ein ganzzahliges Feld.
ActiveRecord::Schema.define do
change_table 'MYTABLE' do |table|
add_column(:mytable, :my_field_name, :integer)
end
end