如何在Rails中编写迁移来重命名ActiveRecord模型及其表?

我在命名方面很糟糕,并且意识到在我的Rails应用程序中有一组更好的模型名称。是否有任何方法使用迁移来重命名模型及其对应的表?

149144 次浏览

这里有一个例子:

class RenameOldTableToNewTable < ActiveRecord::Migration
def self.up
rename_table :old_table_name, :new_table_name
end


def self.down
rename_table :new_table_name, :old_table_name
end
end

我不得不手动重命名模型声明文件。

编辑:

在Rails 3.1 &4、ActiveRecord::Migration::CommandRecorder知道如何反转rename_table迁移,所以你可以这样做:

class RenameOldTableToNewTable < ActiveRecord::Migration
def change
rename_table :old_table_name, :new_table_name
end
end

(你仍然需要手动重命名文件。)

其他答案和评论涵盖了表重命名、文件重命名和代码中的grep。

我想再补充几点注意事项:

让我们使用我今天遇到的一个真实的例子:将一个模型从“Merchant”重命名为“Business”。

  • 不要忘记修改依赖表和模型的名称 同样的迁移。我同时将我的Merchant和MerchantStat模型更改为Business和BusinessStat。否则,在执行搜索和替换时,我将不得不做太多的选择
  • 对于通过外键依赖于您的模型的任何其他模型,其他表的外键列名将从您的原始模型名派生。因此,您还需要在这些依赖模型上执行一些rename_column调用。例如,我不得不在各种连接表(用于has_and_belongs_to_many关系)和其他依赖表(用于正常的has_one和has_many关系)中将'merchant_id'列重命名为'business_id'。否则我最终会得到像‘business_stat’这样的列。Merchant_id '指向'business.id'。这里有一个关于列重命名的好答案。
  • 当grepping时,记得搜索单数,复数,大写, 小写,甚至大写(可能出现在注释中)版本
  • 最好先搜索复数形式,再搜索单数形式。那 如果你用的是不规则复数,比如my merchants:: 举个商业的例子,你可以把所有的不规则复数都拼对。 否则,你可能会以“business”(三个s)作为an结尾 中间状态,导致更多的搜索和替换 不要盲目地替换每一个事件。如果您的模型名称发生冲突 与通用编程术语,与其他模型中的值,或与 在您的视图中添加文本内容,您可能会过于急于求成。 在我的示例中,我想将模型名称更改为“Business”,但是 在我的UI内容中仍然将他们称为“商家”。我在CanCan中也为我的用户设置了一个“商人”角色——正是商人角色和商人模型之间的混淆导致我首先重命名了模型

你还需要替换索引:

class RenameOldTableToNewTable< ActiveRecord:Migration
def self.up
remove_index :old_table_name, :column_name
rename_table :old_table_name, :new_table_name
add_index :new_table_name, :column_name
end


def self.down
remove_index :new_table_name, :column_name
rename_table :new_table_name, :old_table_name
add_index :old_table_name, :column_name
end
end

并重命名您的文件等,手动的其他答案在这里描述。

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

确保在编写迁移之后可以回滚和前滚。如果您犯了一些错误,并且被试图影响不再存在的东西的迁移所困扰,那么这可能会很棘手。如果不能回滚,最好销毁整个数据库并重新开始。所以要注意你可能需要备份一些东西。

另外:检查schema_db中由has_或belongs_to等定义的其他表中的任何相关列名。你可能也需要编辑这些。

最后,在没有回归测试套件的情况下这样做是愚蠢的。

在Rails 4中,我所要做的就是更改def

def change
rename_table :old_table_name, :new_table_name
end

我所有的索引都被照顾好了。我不需要通过删除旧索引和添加新索引来手动更新索引。

它也可以用变化来改变指数的上下变化。

你可以的 执行命令:rails g migration rename_ {old_table_name} {new_table_name} < / p >

在编辑文件并将此代码添加到方法中后,将发生更改

Rename_table:{old_table_name},:{new_table_name}