首页 > 解决方案 > 运行迁移时如何确保 Rails 指向更新的模型名称?

问题描述

我遇到了一个问题,我的一个迁移失败了。这就是现有迁移的样子。

class AddColumnToTwitterPosts < ActiveRecord::Migration[6.0]
  def up
    add_column :twitter_posts, :status, :string, default: "new"
    add_index :twitter_posts, :status

    add_default_status_to_existing_posts
  end

  def down
    remove_column :twitter_posts, :status
  end

  private

    def add_default_status_to_existing_posts
      TwitterPost.find_each do |post|
        post.update!(status: "new")
      end
    end
end

现在我已将模型TwitterPost移至命名空间Twitter::Post

因此,每当此迁移运行时,它都无法找到此模型。如何确保 rails 使用更新的命名空间而不是迁移中指定的旧模型名称?

标签: ruby-on-railspostgresqlactiverecordrails-migrations

解决方案


实际上,您不应该在“模式迁移”中放置任何“数据迁移”。这被认为是不好的做法,正是因为现在给您带来了问题。正如Thoughtbot所建议的,解决问题的一种方法是使用 Rake 任务。如果您需要在特定迁移后更新数据,您可以创建一个 rake 任务来执行您需要的更新。

这样,您的数据库架构迁移将始终有效,因为它们不依赖于您的应用程序中定义的任何特定模型的存在。

在您的情况下,rake 任务可能如下所示:

namespace :twitter_posts do
  desc "Update twitter posts"
  task update_status_new: :environment do
    puts "Going to update #{TwitterPost.count} twitter_posts"

    ActiveRecord::Base.transaction do
      TwitterPost.update_all(status: "new")
    end

    puts " All done now!"
  end
end

推荐阅读