ruby-on-rails - 在Rails迁移时如何重命名数据库列?

  显示原文与译文双语对照的内容

我错误地命名了一个列 hased_password 而不是 hashed_password

如何使用迁移重命名此列?

时间:


rename_column :table, :old_column, :new_column

更新:

你可能需要创建一个单独的迁移来执行这里操作。 ( 按照你的意愿重命名 FixColumnName )


script/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

同时,updown 方法仍然适用。 Rails 3.1接收 "知道如何迁移数据库并在回滚时反转它,而无需编写单独的向下方法"change 方法


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

谢谢,Luke && Turadg,提出主题。


然后就像往常一样,或者你去你的业务。

在这种情况下,imo更好地使用 rake db:rollback 。 然后编辑你的迁移并再次键入 rake db:migrate 。 但是,如果列中有数据,你不想丢失,那么使用 rename_column

http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

Available Transformations

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 在后台。

我意识到这一点更多地涉及到一个流程,但我宁愿这样做,而不考虑我的生产迁移。

从 API:


rename_column(table_name, column_name, new_column_name)

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

某些版本的Rails 支持向上/向下方式迁移到

如果你的迁移中有向上/向下的方法,那么:


def up
 rename_column :table_name, :column_old_name, :column_new_name
end

def down
 rename_column :table_name, :column_new_name, :column_old_name
end

如果迁移中有更改方法,那么:


def change
 rename_column :table_name, :column_old_name, :column_new_name
end

更多信息,你可以移动: http://www.tutorialspoint.com/ruby-on-rails/rails-migrations.htm 或者 http://apidock.com/rails/ActiveRecord/Migration

如果代码没有与其他代码共享,那么最好的选择是只做 rake db:rollback,然后在迁移和 rake db:migrate 中编辑列名。 就是这样

你还可以编写另一个迁移来重命名列


 def change
 rename_column :table_name, :old_name, :new_name
 end

就是这样。

作为替代选择,如果你不嫁给了迁移的概念,有一个引人注目的宝石activerecord将自动处理名称更改,datamapper的风格。 你所做的就是更改模型中的列名( 并确保你将 Model.auto_upgrade ! 在你的模型的底部。rb和 viola ! 数据库即时更新。

https://github.com/DAddYE/mini_record

注意:你将需要使用 db/schema 。rb来防止冲突

仍然处于测试阶段,显然不是针对每个人,但仍然是一个诱人的选择( 我目前在两个non-trivial生产应用中使用它,没有问题)

如果你需要 switch 列名称,你需要创建一个占位符,以避免重复的列名错误 。 下面是一个示例:


class SwitchIp <ActiveRecord::Migration
 def change
 rename_column :styles, :x, :holder
 rename_column :styles, :y, :x
 rename_column :styles, :holder, :y
 end
end

只需创建新的迁移,并在块中使用 rename_column


rename_column :your_table_name, :hashed_password, :hased_password

...