smellman's Broken Diary

クソみたいなもんです

2023/10/04の日記 - Active::Storageをuuidに依存した場合のtest/fixtures/active_storage/attachments.ymlの付き合い方

生活と仕事

今日は10時すぎに起きて11:40ぐらいに公民館へ。

12:00ちょっと前に昼飯に行って、戻ってから仕事へ。

今回はRailsのidをuuidにしたケースで、Active::Storageのminitestで失敗していたのでそこをまとめる。

まず、Active::Storageをuuidにするには以下のmigrationコードが必要。

# frozen_string_literal: true

# change uuid to active storage
class ChangeUuidToActiveStorage < ActiveRecord::Migration[7.0]
  def up
    ActiveRecord::Base.connection.execute('DELETE FROM active_storage_attachments;')
    remove_index :active_storage_attachments, name: :index_active_storage_attachments_uniqueness, unique: true
    change_column_null :active_storage_attachments, :record_id, true, 0
    remove_column :active_storage_attachments, :record_id, :bigint, null: true
    add_column :active_storage_attachments, :record_id, :uuid, null: false, default: ''
    add_index :active_storage_attachments, %i[record_type record_id name blob_id],
              name: :index_active_storage_attachments_uniqueness, unique: true
  end

  def down
    ActiveRecord::Base.connection.execute('DELETE FROM active_storage_attachments;')
    remove_index :active_storage_attachments, name: :index_active_storage_attachments_uniqueness, unique: true
    change_column_null :active_storage_attachments, :record_id, true, ''
    remove_column :active_storage_attachments, :record_id, :uuid, null: false
    add_column :active_storage_attachments, :record_id, :bigint, null: false, default: 0
    add_index :active_storage_attachments, %i[record_type record_id name blob_id],
              name: :index_active_storage_attachments_uniqueness, unique: true
  end
end

この状態で、test/fixtures/active_storage/attachments.ymlで以下のコードでは上手くいかない。

hoge1_image_attachment:
  name: file
  record: hoge1 (Hoge)
  blob: hoge1_image_blob

以下のようにすると上手くいく。

hoge1_image_attachment:
  name: file
  record_type: Hoge
  record_id: A84C23B6-AD0A-4C25-92B5-E3DB5C5D54D3
  blob: hoge1_image_blob

このとき注意が必要なのが、前述のmigrationでActive::Storageでuuidを必須にした影響で、Active::Storageを使うmodelは全てidをuuidにしないといけないということ。

つまり、Fugaモデルが普通のidだった場合にテストコードが一切かけなくなる。

例えば、こんなattachments.ymlはエラーになる。

fuga1_image_attachment:
  name: file
  record_type: Fuga
  record_id: 1
  blob: fuga1_image_blob

結果としてFugaモデルもidをuuidに変更する必要がある。

というわけで、Active::Storageを安易にuuidにするとハマるという話になった。

まぁ、検証コードはまだ書けてないのだけど、これだけ分かったところで今日はタイムアウト

秋葉で飲んでたら何かさんが来てちょっと一緒に飲み。

帰宅してからもちょっと飲んでた。

今日はこんな感じで。

音楽

るびまこと、Ruby My Dearの新譜が出るということで予約注文。

なお、FacebookBreakcore Japanの方にも投稿があったので、承認しておきました。

正式リリース楽しみ!