我错误地将列命名为hased_password而不是hashed_password。

如何使用迁移重命名此列来更新数据库架构?


当前回答

生成迁移文件:

rails g migration FixName

这将创建db/migrate/xxxxxxxxxxx.rb。

编辑迁移以实现您的愿望:

class FixName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end

其他回答

$:  rails g migration RenameHashedPasswordColumn
invoke  active_record
      create    db/migrate/20160323054656_rename_hashed_password_column.rb

打开该迁移文件并按如下方式修改该文件(请输入原始table_name)

class  RenameHashedPasswordColumn < ActiveRecord::Migration
  def change
    rename_column :table_name, :hased_password, :hashed_password
  end
end

从API:

rename_column(table_name, column_name, new_column_name)

这将重命名列,但保持类型和内容不变。

rename_column :table, :old_column, :new_column

您可能需要创建一个单独的迁移来实现这一点。(根据需要重命名FixColumnName。):

bin/rails generate migration FixColumnName
# creates  db/migrate/xxxxxxxxxx_fix_column_name.rb

然后编辑迁移以执行您的意愿:

# db/migrate/xxxxxxxxxx_fix_column_name.rb
class FixColumnName < ActiveRecord::Migration
  def self.up
    rename_column :table_name, :old_column, :new_column
  end

  def self.down
    # rename back if you need or do something else or do nothing
  end
end

对于Rails 3.1,请使用:

尽管向上和向下方法仍然适用,但Rails3.1收到了一个更改方法,该方法“知道如何迁移数据库,并在回滚迁移时反转数据库,而无需编写单独的向下方法”。

有关详细信息,请参阅“活动记录迁移”。

rails g migration FixColumnName

class FixColumnName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end

如果您恰好有一大堆列要重命名,或者需要反复重复表名:

rename_column :table_name, :old_column1, :new_column1
rename_column :table_name, :old_column2, :new_column2
...

您可以使用change_table使事情变得更整洁:

class FixColumnNames < ActiveRecord::Migration
  def change
    change_table :table_name do |t|
      t.rename :old_column1, :new_column1
      t.rename :old_column2, :new_column2
      ...
    end
  end
end

然后只需要db:像往常一样迁移,或者不管你怎么做。


对于轨道4:

在创建用于重命名列的Migration时,Rails4生成了一个更改方法,而不是上一节中提到的上下更改方法。生成的更改方法为:

$ > rails g migration ChangeColumnName

这将创建类似于以下内容的迁移文件:

class ChangeColumnName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end

请参阅“活动记录迁移”文档中的“可用转换”部分。

rename_column(table_name, column_name, new_column_name):

重命名列,但保留类型和内容。

如果该列中已经填充了数据并在生产环境中运行,我建议采用一步一步的方法,以便在等待迁移时避免生产环境中的停机。

首先,我将创建一个数据库迁移,以添加具有新名称的列,并用旧列名的值填充它们。

class AddCorrectColumnNames < ActiveRecord::Migration
  def up
    add_column :table, :correct_name_column_one, :string
    add_column :table, :correct_name_column_two, :string

    puts 'Updating correctly named columns'
    execute "UPDATE table_name SET correct_name_column_one = old_name_column_one, correct_name_column_two = old_name_column_two"
    end
  end

  def down
    remove_column :table, :correct_name_column_one
    remove_column :table, :correct_name_column_two
  end
end

然后我会做出改变,并将其付诸生产。

git commit -m 'adding columns with correct name'

然后,一旦提交被推到生产中,我就会运行。

Production $ bundle exec rake db:migrate

然后,我会将引用旧列名的所有视图/控制器更新为新列名。运行我的测试套件,并提交这些更改。(确保它在本地工作并首先通过所有测试后!)

git commit -m 'using correct column name instead of old stinky bad column name'

然后我会把这个承诺推向生产。

此时,您可以删除原始列,而不必担心与迁移本身相关的任何停机时间。

class RemoveBadColumnNames < ActiveRecord::Migration
  def up
    remove_column :table, :old_name_column_one
    remove_column :table, :old_name_column_two
  end

  def down
    add_column :table, :old_name_column_one, :string
    add_column :table, :old_name_column_two, :string
  end
end

然后将最新的迁移推送到生产环境,并在后台运行bundle exec rake db:migrate。

我意识到这是一个更复杂的过程,但我宁愿这样做,也不想在生产迁移中遇到问题。