ruby on rails-如何部署删除模型的迁移



我正在重构一个大型Rails应用程序,并对一个非常神秘的数据库结构进行大量更改。这包括删除许多表和模型,将数据放入数据库的其他部分。

为了使情况更清楚,假设我正在将不必要的user_level表中的数据移动到user表中。到目前为止,我所做的是:

  • 创建一个迁移,将access_level列添加到user表中,然后执行以下操作:

    每个用户|u.access_level=u.user_level.level结束

  • 运行迁移。将其输入git。

  • user.rb中删除user_level模型和关联。把它输入git
  • 创建一个删除user_level表的迁移。运行它并将其检查为git

这在开发中非常有效,但我不知道如何将其部署到生产服务器上。目前,我们相当不雅的部署过程是在服务器上运行git pull,然后执行任何需要的db:migrate或类似操作。但如果我们这样做,当我们git pull将代码更新为head,然后尝试迁移时,UserLevel模型就不存在了,因此u.user_level.level将失败。(我对使用Capistrano这样的东西持开放态度,但我不知道在这种情况下这是否也有帮助。)

如果有一种方法可以依次签出每个git提交,并在每次提交后运行db:migrate,这一切都会非常完美,但我不知道如何做到这一点,我相信这一定是一个解决了的问题。我该怎么做?

因为代码更新是在部署期间迁移之前运行的,所以您删除的模型不再存在。

我认为您可以使用纯sql命令来代替ruby代码User.all.each do |u| u.access_level = u.user_level.level end

是的,您可以使用git checkout来获取给定提交的代码。例如:

git checkout 4ddcd26652a9516aecff7a7e17f4c324bdb8f6dd

其中4ddcd26652a9516aecff7a7e17f4c324bdb8f6dd将是提交哈希。

因此,对于您的案例,您可以为特定提交执行git pull,然后执行git checkout。运行迁移后,您可以移回master。

尽管如此,您未来的最佳选择是避免在迁移文件中直接使用模型(或任何其他外部依赖项)。一种方法是在迁移中定义模型(我只是猜测模型可能是什么样子):

class AddAccessLevelToUser < ActiveRecord::Migration
  class UserLevel < ActiveRecord::Base
    belongs_to :user
  end
  def up
    add_column :users, :access_level, :string
    UserLevel.each do |user_level|
      user = user_level.user
      user.access_level = user_level.access_level
      user.save!
    end
  end
  def down
    remove_column :users, :access_level
  end
end

您也可以简单地在迁移文件本身中编写SQL。通过Andrey Koleshko的Change Migrations like a Boss了解更多信息。

删除对模型的依赖将防止出现人们试图从零开始关闭应用程序并运行所有迁移的问题。

进行所有重构,但不要立即删除模型或底层表,怎么样?在单独的后续重构中执行此操作。

最新更新