Ruby-on-rails 将时间戳添加到现有表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7542976/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 02:02:08  来源:igfitidea点击:

Add timestamps to an existing table

ruby-on-railsrubyrails-activerecordrails-migrations

提问by leonel

I need to add timestamps (created_at& updated_at) to an existing table. I tried the following code but it didn't work.

我需要将时间戳 ( created_at& updated_at)添加到现有表中。我尝试了以下代码,但没有用。

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

回答by Ben Simpson

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

时间戳助手仅在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

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

虽然这与add_timestamps您在上面指定的方法没有相同的简洁语法,但 Rails 仍会将这些列视为时间戳列,并正常更新值。

回答by mu is too short

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

迁移只是两个类方法(或 3.1 中的实例方法):updown(有时是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

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

如果您在 3.1 中,那么您还可以使用change(感谢 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.

也许你会迷惑def changedef change_tablechange_table

See the migration guidefor further details.

有关更多详细信息,请参阅迁移指南

回答by georgebrock

Your original code is very close to right, you just need to use a different method name. If you're using Rails 3.1 or later, you need to define a changemethod instead of change_table:

您的原始代码非常接近正确,您只需要使用不同的方法名称。如果您使用的是 Rails 3.1 或更高版本,则需要定义一个change方法而不是change_table

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

If you're using an older version you need to define upand downmethods instead of change_table:

如果您使用的是旧版本,则需要定义updown方法而不是change_table

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

  def down
    remove_timestamps(:users)
  end
end

回答by Nick Davies

@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.

@user1899434 的回复基于这样一个事实,即此处的“现有”表可能意味着其中已包含记录的表,您可能不想删除的记录。因此,当您添加带有 null: false 的时间戳时,这是默认的并且通常是可取的,这些现有记录都是无效的。

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:

但是我认为可以通过将两个步骤合并为一个迁移以及使用更具语义的 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

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.

您可以将其他时间戳替换为DateTime.now,例如,如果您希望在开始时创建/更新预先存在的记录。

回答by Pradeep Sanjaya

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

http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html

回答by lightyrs

Nick Davies answeris the most complete in terms of adding timestamp columns to a table with existing data. Its only downside is that it will raise ActiveRecord::IrreversibleMigrationon a db:rollback.

Nick Davies 的答案是将时间戳列添加到具有现有数据的表中最完整的答案。它唯一的缺点是它会ActiveRecord::IrreversibleMigrationdb:rollback.

It should be modified like so to work in both directions:

它应该像这样修改以在两个方向上工作:

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

回答by Ian Vaughan

def change
  add_timestamps :table_name
end

回答by Reef Loretto

not sure when exactly this was introduced, but in rails 5.2.1 you can do this:

不确定这是什么时候引入的,但在 Rails 5.2.1 中你可以这样做:

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

for more see "using the change method" in the active record migrations docs.

有关更多信息,请参阅活动记录迁移文档中的“使用更改方法”。

回答by Roger

I made a simple function that you can call to add to eachtable (assuming you have a existing database) the created_atand updated_atfields:

我做了一个简单的函数,你可以调用它来添加到每个表(假设你有一个现有的数据库)created_atupdated_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

回答by almawhoob

add_timestamps(table_name, options = {}) public

add_timestamps(table_name, options = {}) public

Adds timestamps (created_at and updated_at) columns to table_name. Additional options (like null: false) are forwarded to #add_column.

将时间戳(created_at 和 updated_at)列添加到 table_name。附加选项(如 null: false)被转发到 #add_column。

class AddTimestampsToUsers < ActiveRecord::Migration
  def change
    add_timestamps(:users, null: false)
  end
end