Just do IT

思うは招く

rails db:rollback → マイグレーションファイル修正 → マイグレート再実行の流れ

ロールバック怖い。でもやらなければ・・・

ロールバックの手順をメモした。

背景

  • logsテーブルの id を uuid に変更したい
  • でもすでに logs テーブルは作っちゃった
  • 幸い、ひとつロールバックすればまだ戻せる
  • DB は postgresql を使用

今の DB バージョンを確認しておく。

$ bin/rails db:version
Current version: 20200902003815

ペンディングしてるマイグレーションがないかチェック。

$ bin/rails db:abort_if_pending_migrations

今の schema.rb にはlogsテーブルの内容が記載されている。

create_table "logs", force: :cascade do |t|
    t.string "title", null: false
    t.text "description", null: false
    t.bigint "article_id", null: false
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["article_id"], name: "index_logs_on_article_id"
  end

これが消えたら成功。

ロールバック実行。

bin/rails db:rollback

消えた!

なお、ロールバックをした際は、データを含む場合はデータは削除される。

次に、logsテーブルを作ったときのマイグレーションファイルを修正する。id を uuid に変更する。

class CreateLogs < ActiveRecord::Migration[6.0]
  def change
    create_table :logs do |t|
      t.string :title, null: false
      t.text :description, null: false
      t.references :article, null: false, foreign_key: true

      t.timestamps
    end
  end
end

これを以下のように変更する。

class CreateLogs < ActiveRecord::Migration[6.0]
  def change
    enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto')
    create_table :logs, id: :uuid, default: 'gen_random_uuid()' do |t|
      t.string :title, null: false
      t.text :description, null: false
      t.references :article, null: false, foreign_key: true

      t.timestamps
    end
  end
end

関連:Rails + PostgreSQL で id を uuid に変更したい - Just do IT

マイグレート再実行。

$ bin/rails db:migrate

結果はこちら。成功した。

$ bin/rails db:migrate
== 20200902003815 CreateLogs: migrating =======================================
-- extension_enabled?("pgcrypto")
   -> 0.0271s
-- enable_extension("pgcrypto")
   -> 0.0249s
-- create_table(:logs, {:id=>:uuid, :default=>"gen_random_uuid()"})
   -> 0.0107s
== 20200902003815 CreateLogs: migrated (0.0629s) ==============================

試しにテストデータを入れてみる。

log = Log.create(article_id: 7, title: "テストログ1", description: "テストログ詳細1")
log = Log.create(article_id: 7, title: "テストログ2", description: "テストログ詳細2")

補足:記事モデルを参照しているので外部キーとしてarticle_idを入れている。

ログのIDがUUIDになった!

irb(main):003:0> log.id
=> "554c728a-41b0-43b2-a7d7-cc9631660880"