leo*_*nel 161 ruby ruby-on-rails rails-migrations rails-activerecord
我需要将时间戳(created_at updated_at)添加到现有表.我尝试了以下代码,但它没有用.我也尝试过我在网上找到的其他解决方案,但它们也不起作用.
class AddTimestampsToUser < ActiveRecord::Migration
def change_table
add_timestamps(:users)
end
end
Run Code Online (Sandbox Code Playgroud)
我该怎么做?
Ben*_*son 202
时间戳帮助程序仅在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
Run Code Online (Sandbox Code Playgroud)
虽然这与add_timestamps上面指定的方法没有相同的简洁语法,但Rails仍将这些列视为时间戳列,并正常更新值.
mu *_*ort 86
迁移只是两个类方法(或3.1中的实例方法):up和down(有时change3.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
Run Code Online (Sandbox Code Playgroud)
如果您在3.1中,那么您也可以使用change(感谢Dave):
class AddTimestampsToUser < ActiveRecord::Migration
def change
change_table(:users) { |t| t.timestamps }
end
end
Run Code Online (Sandbox Code Playgroud)
也许你会迷惑def change,def change_table和change_table.
有关更多详细信息,请参阅迁移指南
geo*_*ock 72
您的原始代码非常接近正确,您只需要使用不同的方法名称.如果您使用的是Rails 3.1或更高版本,则需要定义一个change方法而不是change_table:
class AddTimestampsToUser < ActiveRecord::Migration
def change
add_timestamps(:users)
end
end
Run Code Online (Sandbox Code Playgroud)
如果您使用的是旧版本,则需要定义up和down方法,而不是change_table:
class AddTimestampsToUser < ActiveRecord::Migration
def up
add_timestamps(:users)
end
def down
remove_timestamps(:users)
end
end
Run Code Online (Sandbox Code Playgroud)
Nic*_*ies 45
@ 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
Run Code Online (Sandbox Code Playgroud)
您可以替换其他时间戳DateTime.now,例如,如果您希望在时间的早晨创建/更新预先存在的记录.
Pra*_*aya 38
class AddTimestampsToUser < ActiveRecord::Migration
def change
change_table :users do |t|
t.timestamps
end
end
end
Run Code Online (Sandbox Code Playgroud)
可用的转换是
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
Run Code Online (Sandbox Code Playgroud)
http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html
就将时间戳列添加到具有现有数据的表而言,Nick Davies的答案是最完整的。它唯一的缺点是,它会提高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
Run Code Online (Sandbox Code Playgroud)
这里大多数答案的问题是,如果您默认为Time.zone.now所有记录,则会将迁移运行的时间作为默认时间,这可能不是您想要的。在 rails 5 中,您可以改为使用now(). 这会将现有记录的时间戳设置为运行迁移的时间,以及新插入记录的提交事务的开始时间。
class AddTimestampsToUsers < ActiveRecord::Migration
def change
add_timestamps :users, default: -> { 'now()' }, null: false
end
end
使用Time.current是一种很好的风格https://github.com/rubocop-hq/rails-style-guide#timenow
def change
change_table :users do |t|
t.timestamps default: Time.current
t.change_default :created_at, from: Time.current, to: nil
t.change_default :updated_at, from: Time.current, to: nil
end
end
Run Code Online (Sandbox Code Playgroud)
或者
def change
add_timestamps :users, default: Time.current
change_column_default :users, :created_at, from: Time.current, to: nil
change_column_default :users, :updated_at, from: Time.current, to: nil
end
Run Code Online (Sandbox Code Playgroud)
这看起来像是 Rails 5.0.7 中的一个干净的解决方案(发现了change_column_null方法):
def change
add_timestamps :candidate_offices, default: nil, null: true
change_column_null(:candidate_offices, :created_at, false, Time.zone.now)
change_column_null(:candidate_offices, :updated_at, false, Time.zone.now)
end
Run Code Online (Sandbox Code Playgroud)
小智 5
不确定这是什么时候引入的,但在 Rails 5.2.1 中你可以这样做:
class AddTimestampsToMyTable < ActiveRecord::Migration[5.2]
def change
add_timestamps :my_table
end
end
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅活动记录迁移文档中的“使用更改方法”。
我在 Rails 5.0 上,但这些选项都不起作用。
唯一有效的是使用类型为 :timestamp 而不是 :datetime
def change
add_column :users, :created_at, :timestamp
add_column :users, :updated_at, :timestamp
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
80161 次 |
| 最近记录: |