既存のテーブルにタイムスタンプ(created_at
&updated_at
)を追加する必要があります。次のコードを試しましたが、うまくいきませんでした。
class AddTimestampsToUser < ActiveRecord::Migration
def change_table
add_timestamps(:users)
end
end
タイムスタンプヘルパーは、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はこれらの列をタイムスタンプ列として扱い、値を通常どおり更新します。
移行は、2つのクラスメソッド(または3.1のインスタンスメソッド):up
およびdown
(および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 change
、def change_table
、およびchange_table
を混同している可能性があります。
詳細については、 移行ガイド をご覧ください。
元のコードは非常に近く、別のメソッド名を使用するだけです。 Rails 3.1以降を使用している場合、change_table
の代わりにchange
メソッドを定義する必要があります。
class AddTimestampsToUser < ActiveRecord::Migration
def change
add_timestamps(:users)
end
end
古いバージョンを使用している場合は、change_table
の代わりにup
およびdown
メソッドを定義する必要があります。
class AddTimestampsToUser < ActiveRecord::Migration
def up
add_timestamps(:users)
end
def down
remove_timestamps(:users)
end
end
@ user1899434の応答は、ここにある「既存の」テーブルとは、ドロップしたくないかもしれないレコードがすでに含まれているテーブルを意味する可能性があるという事実を取り上げたものです。したがって、null:falseのタイムスタンプを追加すると、これがデフォルトであり、多くの場合望ましいのですが、これらの既存のレコードはすべて無効です。
しかし、2つのステップを1つの移行に組み合わせ、より意味のある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
の代わりに他のタイムスタンプを使用できます。
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
def change
add_timestamps :table_name
end
Nick Davies answer は、既存のデータを含むテーブルにタイムスタンプ列を追加するという点で最も完全です。唯一の欠点は、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
これが正確にいつ導入されたかはわかりませんが、Rails 5.2.1ではこれを行うことができます。
class AddTimestampsToMyTable < ActiveRecord::Migration[5.2]
def change
add_timestamps :my_table
end
end
詳細については、アクティブレコード移行ドキュメントの「 change methodを使用 」を参照してください。
eachテーブル(既存のデータベースがある場合)に追加するために呼び出すことができる単純な関数を作成しましたcreated_atおよびpdated_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
add_timestamps(table_name、options = {})public
タイムスタンプ(created_atおよびupdated_at)列をtable_nameに追加します。追加オプション(null:falseなど)は#add_columnに転送されます。
class AddTimestampsToUsers < ActiveRecord::Migration
def change
add_timestamps(:users, null: false)
end
end
ここにはたくさんの答えがありますが、私も投稿します。なぜなら、以前のものはどれも本当に役に立たなかったからです:)
一部の人が指摘しているように、残念ながら#add_timestamps
はnull: false
制限を追加します。これにより、これらの値が設定されていないため、古い行が無効になります。ここでのほとんどの答えは、デフォルト値(Time.zone.now
)を設定することを示唆していますが、古いデータのこれらのデフォルトのタイムスタンプが正しくないため、私はそれを行いたくありません。間違ったデータをテーブルに追加しても値がわかりません。
だから私の移行は単純に:
class AddTimestampsToUser < ActiveRecord::Migration
def change_table
add_column :projects, :created_at, :datetime
add_column :projects, :updated_at, :datetime
end
end
null: false
なし、その他の制限なし。古い行は、created_at
がNULL
として、update_at
がNULL
として有効になります(行に何らかの更新が実行されるまで)。新しい行には、created_at
およびupdated_at
が期待どおりに入力されます。
前の答えは正しいように見えますが、テーブルにすでにエントリがある場合、問題に直面しました。
「エラー:列created_at
にはnull
値が含まれています」が表示されます。
修正するために、私は使用しました:
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
その後、この移行後に作成されたすべてのプロジェクトが正しく更新されます。 Rails ActiveRecord
がレコードのタイムスタンプの追跡を開始するように、サーバーも再起動されていることを確認してください。
Railsの場合はchange_table
ではなくchange
です4.2:
class AddTimestampsToUsers < ActiveRecord::Migration
def change
add_timestamps(:users)
end
end
Railsを使用せずにactiverecordを使用する場合は、次の例も既存のモデルに列を追加します。例は整数フィールドです。
ActiveRecord::Schema.define do
change_table 'MYTABLE' do |table|
add_column(:mytable, :my_field_name, :integer)
end
end