0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Railsマイグレーション変更時の注意点とJSON型移行|既存データ変換も解説

Posted at

はじめに

この記事では、Railsアプリ開発時にマイグレーションファイルの変更が必要な場面で、どう対応すれば良いかを具体的に説明します。

この記事でわかる・できること

  • マイグレーション未適用時のファイル修正方法
  • 適用済みマイグレーションの正しい修正手順
  • データ型変更(text→json)時の既存データ変換例

この記事の対象者

  • Rails初心者
  • APIサーバ構築者
  • DBマイグレーション実務者

動作環境・使用するツールや言語

  • OS: macOS Sequoia 15.5
  • ツール: VSCode 1.102.1
  • 言語: Ruby 3.4.4/Rails 8.0.2
  • DB: PostgreSQL

Rails で マイグレーションファイルを変更したい場合 は、状況によって手順が変わります。
順番に整理していきましょう。

1. マイグレーションファイルとは

データベースの構造はアプリケーションの仕様変更により、必要に応じて追加や削除が繰り返されます。
この変更作業が「マイグレーション」です。

マイグレーションを行うためには、まずマイグレーションファイルを作成します。
このファイルに変更内容を書き込むことで、Railsが自動的にデータベースを更新してくれるのです。
Railsすごい!

以下のコマンドで、マイグレーションファイルを作成して

rails generate migration CreateUsers

作成したマイグレーションファイルは「db/migrate」ディレクトリの中に保存されます。
ファイルを開くと、以下のようなコードが書かれています。

# 20251203000000_create_users.rb
class CreateUsers < ActiveRecord::Migration[8.0]
  def change
  end
end

ここに、ユーザーの名前とメールアドレスといいねを保存するためのテーブルを作成する場合、以下のように書きます。

class CreateUsers < ActiveRecord::Migration[8.0]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email
      t.string :likes

      t.timestamps
    end
  end
end

このマイグレーションファイルをデータベースへ反映させるために、以下のコマンドを実行します。

rails db:migrate

マイグレーションファイルは一度実行(マイグレート)されると、マイグレーションファイルを直接編集しても、その変更はデータベースに反映されません。
これはよく見られる間違いの一つです。

2. マイグレーションファイル変更方法(db:migrate 前)

マイグレート前は そのマイグレーションファイルを直接編集して OKです。
Rails はまだ schema_migrations に記録していないので、自由に変更可能になります。

RailsはAPIとして、フロントエンドから呼び出されることが多いため、emailカラムのデータ型をstring型からJSON型に変更してみます。
現代のWeb/API連携はJSON形式が標準です。
DBに「json型」として格納しておけば、そのままフロントにJSON返却することができます。

例:likes を text → json に変更したい場合

# db/migrate/20251203000000_create_users.rb
class CreateUsers < ActiveRecord::Migration[8.0]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email
      # string型からjson型に変更
      t.json :likes

      t.timestamps
    end
  end
end

変更後は普通に rails db:migrate を実行すれば OKです。

3. マイグレーションファイル変更方法(db:migrate 後)

マイグレート後は直接編集しても DB は変わりません
この場合は新しいマイグレーションファイルを作るのが正しい方法です。

※マイグレーションファイルを新規作成せずに、データベース構造を変更することもできるそうです。
詳しくは以下をご覧ください。

しかし、明らかな人為ミスや個人開発以外では、新しくマイグレーションファイルを作成することをおすすめします。
すでに適用済みのマイグレーションを直接変更・ロールバックすると他メンバーのDBとの整合性にトラブルが出やすくなるからです。

例1:likes カラムを削除したい場合

以下のコマンドで、マイグレーションファイルを作成します。

rails generate migration RemoveLikesFromUsers

生成されたマイグレーションファイルに、以下のように削除したい「カラム」の情報を書きます。

class RemoveLikesFromUsers < ActiveRecord::Migration[8.0]
  def change
    remove_column :users, :likes
  end
end

これで、usersテーブルからlikesという「カラム」が削除されます。

例2:likes を text型 → json型 に変更したい場合

rails generate migration ChangeLikesToJsonInUsers

生成されたマイグレーションに書く:

class ChangeLikesToJsonInUsers < ActiveRecord::Migration[8.0]
  def change
    change_column :users, :likes, :json
  end
end

その後、マイグレーションを実行します。

rails db:migrate

このマイグレーションを実行すると、usersテーブルのlikesカラムの型がjson型に変更されます。

4. JSON型移行の注意点 : 既存データの移行

すでに text 型でデータ保存してある場合は、マイグレーションする前に データ変換が必要です。
ここでは、いいねしたユーザーとそのユーザー情報がYAMLファイル形式で保存されているとします。

liked_users:
  - id: 1
    name: 田中太郎
    email: taro@example.com
    age: 28
    liked_at: 2023-11-20T15:23:01Z
  - id: 2
    name: 鈴木花子
    email: hanako@example.com
    age: 25
    liked_at: 2023-11-21T10:05:17Z

likesカラムはtext型なので、以下の形式で保存されています。

"liked_users:\n  - id: 1\n    name: 田中太郎\n    email: taro@example.com\n    age: 28\n    liked_at: 2023-11-20T15:23:01Z\n  - id: 2\n    name: 鈴木花子\n    email: hanako@example.com\n    age: 25\n    liked_at: 2023-11-21T10:05:17Z\n"

この形式だと、フロントエンドのプログラムがJSONを要求している場合、データ受信されません。

YAML → JSON に変換する例(マイグレーション前に)

Rails コンソールで以下を実行します。

Users.find_each do |s|
  # YAML文字列を配列に変換してから JSON に変換して保存
  data = YAML.safe_load(s.likes)
  s.update_column(:likes, data.to_json)
end

これで likes カラムのデータ型を JSON型 へ変換することができます。

修正マイグレーション例

class ChangeLikesToJsonInUsers < ActiveRecord::Migration[8.0]
  def up
    # likes カラムに保存されている YAML文字列を JSON に変換
    change_column :users, :likes, :json
 end

  def down
    change_column :users, :likes, :text
  end
end

最後にマイグレーションを実行します。

rails db:migrate      # upが適用される
rails db:rollback     # downが適用される

likesカラムには以下のようにjson型で保存されます。

{
  "liked_users": [
    {
      "id": 1,
      "name": "田中太郎",
      "email": "taro@example.com",
      "age": 28,
      "liked_at": "2023-11-20T15:23:01Z"
    },
    {
      "id": 2,
      "name": "鈴木花子",
      "email": "hanako@example.com",
      "age": 25,
      "liked_at": "2023-11-21T10:05:17Z"
    }
  ]
}

手順まとめ

  1. Rails コンソールで YAML → JSON に変換して保存
  2. 新しいマイグレーションで change_column :likes, :json を実行
  3. rails db:migrate で型変更を適用

まとめ

マイグレーションファイルは、データベース構造を変更するための設計図です。
Railsはこのファイルを基にrails db:migrateコマンドでデータベースを更新します。

db:migrateを実行した後は、マイグレーションファイルを直接編集してもデータベースには反映されません。
この場合は、新しいマイグレーションファイルを作成して変更することが基本的な方法です。

既存データの整合性を保つため、変換処理も忘れないようにしましょう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?