LoginSignup
3
1

More than 3 years have passed since last update.

[Rails]stringからenumに変更する

Last updated at Posted at 2019-09-29

stringで保存されたデータをenumに変更します。

enumの設定

ゴールとなるenumの設定。

Reservation.rb
class Reservation < ApplicationRecord
    enum status: { applied: 0, accepted: 1, cancelled: 2, completed: 3 }
end

migrationの設定

元データは、Reservation.statusにstringで'applied','accepted','cancelled','completed'が入っています。

以下のようなマイグレーションで、カラム型をStringからIntegerに変更し、データも移行するところまで一括で行います。

class ReservationStatusConvertToEnum < ActiveRecord::Migration[6.0]
  # データベース操作の際にコールバックを呼ばないよう、テーブルを使うだけのTmpモデルを作る
  class TmpReservation < ApplicationRecord
    self.table_name = :reservations
  end

  def change
    # 元データのカラム名を変更
    change_table :reservations do |t|
      t.rename :status, :old_status
    end

    reversible do |dir|
      dir.up do
         # 新しくenum用のintegerカラムを追加
        add_column :reservations, :status, :integer, null: false, default: 0
        # テーブル情報をリセットする
        TmpReservation.reset_column_information
        # stringで持っていた名前をenumと同じ順でarrayにし、旧データをインデックス番号で取る
        TmpReservation.find_each do |tr|
          tr.status = %w(applied accepted cancelled completed).index(tr.old_status)
          tr.save!
        end
        # 旧データを捨てる
        remove_column :reservations, :old_status
      end

      # upの逆
      dir.down do
        add_column :reservations, :old_status, :string
        TmpReservation.reset_column_information
        TmpReservation.find_each do |tr|
          r = Reservation.find(tr.id)
          tr.old_status = r.status
          tr.save!
        end
        remove_column :reservations, :status
      end
    end
  end
end

参考: Rails Migration, converting from string to enum | stack overflow

Scopeの修正

条件をSQL形式で書いてしまっているところは、enumに変換後に期待するデータが取ってこれなくなりますので、修正します。

scope :applied_reservations, -> { where("status = 'applied'") } # NG
scope :applied_reservations, -> { where(status: 'applied') } # OK

3
1
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
3
1