LoginSignup
4
2

Rails7.0.8でsqliteに対してchange_columnするときは必要な全ての要素を指定しよう

Last updated at Posted at 2024-03-20

最初にざっくりまとめ

  • Rails7.0.8sqlitechange_columnに対して変更が入った
  • その影響で以前とは振る舞いが変わっている
    • change_columnで指定した要素以外の設定がデフォルトに戻ってしまう
  • mysqlでは起きない(検証してないけど多分sqlite以外は大丈夫)

つまり、 Rails7.0.8sqliteに対してchange_columnするときは必要な全ての要素を指定しよう

調べたこと

Rails7.0.8のリリースノート

色々と機能がリリースされていますが、今回の事象に関わるのは以下。この修正でsqlitechange_columnに対して実装が追加されています。

Fix change_column not setting precision: 6 on datetime columns when using 7.0+ Migrations and SQLite.

Hartley McGuire

Rails7.0.7.2Rails7.0.8で挙動比較

検証バージョン

  • Ruby: 3.2.2
  • sqlite3: 3.39.2

マイグレーションファイルを2つ用意します。一つはテーブル作成で、その際にdefaultnullを指定しておきます。もう一つはカラム変更で、属性としてコメントだけを指定します。命名が適当なのは許して🙏

テーブル作成マイグレーション
class CreateTestTable < ActiveRecord::Migration[7.0]
  def change
    create_table :test_tables do |t|
      t.string :name, null: false, default: 'name'

      t.timestamps
    end
  end
end
カラム変更マイグレーション
class ChangeTestTableColumn < ActiveRecord::Migration[7.0]
  def change
    change_column :test_tables, :name, :string, comment: 'changed'
  end
end

この二つのマイグレーションを実行すると、sqliteのテーブル定義は以下のようになりました。

Rails7.0.7.2の場合
CREATE TABLE IF NOT EXISTS "test_tables" (
  "id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
  "name" varchar DEFAULT 'name' NOT NULL,
  "created_at" datetime(6) NOT NULL,
  "updated_at" datetime(6) NOT NULL
);
Rails7.0.8の場合
CREATE TABLE IF NOT EXISTS "test_tables" (
  "id" integer NOT NULL PRIMARY KEY,
  "name" varchar, -- DEFAULT 'name' NOT NULL が消えてしまった!
  "created_at" datetime(6) NOT NULL,
  "updated_at" datetime(6) NOT NULL
);

Rails7.0.7.2以前は、change_columnで指定した要素以外は、それまでの設定を引き継いでくれていました。
Rails7.0.8では、change_columnで指定した要素以外の設定はデフォルトに戻るようになりました。

ちなみに、mysqlを使った場合はどちらのバージョンでもRails7.0.7.2xsqliteの挙動と同じでした。

解決策

change_columnを使うときは、サボらず必要な要素を全部書きましょう。

カラム変更マイグレーション修正版
class ChangeTestTableColumn < ActiveRecord::Migration[7.0]
  def change
    change_column :test_tables, :name, :string, null: false, default: 'name', comment: 'changed'
  end
end

終わりに

今回はテストが通らなくなったことでこの事象に気づくことができました。テストって大事👏
本番環境でsqliteを使っているプロダクトは少ないと思うので、そこまで影響はないと思いますが、振る舞いが変わるのは怖いですね。バージョンアップする際は動作確認しっかりやりましょう💪

4
2
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
4
2