如何确保 Rails 在 运行 迁移时指向更新的模型名称?

How to make sure Rails points to updated model name when running a migration?

我 运行 遇到一个问题,其中一个迁移失败。这是现有迁移的样子。

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 选择更新的命名空间而不是迁移中指定的旧模型名称?

实际上你不应该在你的“模式迁移”中放置任何“数据迁移”。这被认为是不好的做法,正是由于现在给您带来问题的原因。解决问题的一种方法是使用 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