当我的迁移引用一个不存在的类时,我应该怎么做?



My Migration引用了一个不存在的类:

class AddDataToUsers < ActiveRecord::Migration[4.2]
def up
UsersService.load_data
end
def down
User.delete_all
end
end

UsersService被删除了,但我仍然有这个旧的迁移引用它。

开发者现在无法从一开始就运行迁移。我应该如何处理它来修复我的迁移?

我已经尝试更改旧的迁移文件来检查是否定义了UserService类。我不确定这是不是一个好的做法。

只要在所有环境(如developmentstagingproduction)上运行旧的迁移就删除它们。保留旧的迁移文件几乎没有什么好处。

为应用程序设置一个空数据库,使用rails db:schema:load比使用rails db:migrate要快得多。db:schema:load创建一个数据库,其中所有的表和列都按照schema.rb中描述的方式配置。

或者,无论如何您都需要将最新的数据库转储文件导入到新数据库中。在这些情况下,也不需要运行迁移。

因此,我通常每隔几周删除一次旧的迁移。当您删除旧的迁移时,通常不会遇到您所描述的问题。

这实际上是在官方Rails指南中推荐的,正如max指出的:

6.1模式文件是用来做什么的?

迁移虽然很强大,但并不是数据库模式的权威来源。您的数据库仍然是权威的来源。默认情况下,Rails生成db/schema.rb,它试图捕获数据库模式的当前状态。

通过bin/rails db:schema:load加载模式文件创建应用程序数据库的新实例往往比重播整个迁移历史更快,更不容易出错。如果旧的迁移使用了不断变化的外部依赖项,或者依赖于与您的迁移分开发展的应用程序代码,那么旧的迁移可能无法正确应用。

如果您想快速查看活动记录对象具有哪些属性,模式文件也很有用。该信息不在模型的代码中,并且经常分布在多个迁移中,但是该信息在模式文件中得到了很好的总结。

作为最佳实践,您不应该在迁移中引用模型(或其他类!)。如果你需要加载/修改/删除数据,你应该为它创建一个rake任务,而不是一个迁移。

在你的例子中,既然错误已经发生了,你必须以某种方式进行补救。由于在这种特殊情况下,看起来您正在将数据加载到一个不再存在的表中,因此只删除此迁移或注释引用不存在模型的行应该是安全的。

记住"正确的事要做";在问题的不同情况下会有所不同。

@spickermann并没有错,因为您可以潜在地删除已经在任何地方运行并依赖db/schema.rb文件的旧迁移。然而,我更喜欢"压扁"。将旧的迁移到单个文件中,获得相同的速度优势,但不会破坏Rails对db:migrate从一个新数据库工作的期望。

最新更新