ChatGPT解决这个技术问题 Extra ChatGPT

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

我不擅长命名,并意识到在我的 Rails 应用程序中有一组更好的模型名称。有没有办法使用迁移来重命名模型及其对应的表?

我建议在这个问题中添加“ActiveRecord”以改进搜索引擎匹配。我一直在寻找这个使用“ActiveRecord 重命名表”。
如果您使用迁移,这个问题比看起来更复杂。选择的解决方案说在您更改表名后返回并手动重命名模型、控制器等。如果您这样做,所有以旧名称引用您的模型的旧迁移都将失败。因此,当有人克隆您的存储库并尝试运行 rake db:migrate 时,它将失败。您可以返回并在迁移中更改这些名称,但这会变得一团糟。您最好创建一个全新的模型而不是重命名它。
@andrewhannigan:如果有人克隆你的 repo 并运行 rake db:schema:load,你的观点不是没有意义吗?
@istrasci:绝对。事实上,我们不鼓励从头开始运行 rake db:migrate 来建立数据库,这正是由于 Andrew 所指出的问题。

n
ndnenkov

这是一个例子:

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

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


@mathee:是的,您必须手动更改它,或者使用可以进行 Ruby 重构并将其提交到您的版本控制系统的 IDE。
git grep 是你的朋友。我现在正在将活动重命名为习惯:git grep -i activit 非常有启发性。
您还必须更改控制器的内容,对吗?
并且不要忘记您的 routes.rb!
另外,请注意,您希望在 rename_table 调用中使用表名的复数形式。
b
bfcoder

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

def change
  rename_table :old_table_name, :new_table_name
end

我所有的索引都为我处理好了。我不需要通过删除旧索引并添加新索引来手动更新索引。

它也可以使用索引的上升或下降变化来工作。


C
Community

其他答案和评论包括表重命名、文件重命名和通过代码查找。

我想补充一些注意事项:

让我们使用我今天遇到的一个真实示例:将模型从“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 时,请记住搜索字符串的单数、复数、大写、小写甚至大写(可能出现在注释中)版本。

最好先搜索复数版本,然后再搜索单数。这样,如果您有不规则复数 - 例如在我的商人 :: 企业示例中 - 您可以正确获取所有不规则复数。否则,您最终可能会以“businesss”(3 s)作为中间状态,从而导致更多的搜索和替换。

不要盲目地替换每一次出现。如果您的模型名称与常见的编程术语、其他模型中的值或视图中的文本内容相冲突,您最终可能会过于急切。在我的示例中,我想将模型名称更改为“业务”,但在 UI 的内容中仍将它们称为“商家”。在 CanCan 中,我还为我的用户设置了一个“商人”角色——正是商人角色和商人模型之间的混淆导致我首先重命名了该模型。


R
Rimian

您还需要替换索引:

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.0.0.beta1 迁移,不需要手动更新索引。 AR 会自行更新。
M
Mouhamadou Bamba Mboup

您可以执行以下命令: rails g migration rename_{old_table_name}to{new_table_name}

编辑文件并在方法更改中添加此代码后

重命名表:{old_table_name},:{new_table_name}