miyohideの日記

技術的なメモなどを記しています

2018年12月10日(月)

冬将軍到来って感じ。引きこもりたい。

standalone-migrations

先日「PostgreSQLでcreate tableってどう書くの?」って疑問にぶち当たりました。大体雰囲気では分かっていたのですが、auto incrementとか主キーの設定とか型とかいろいろとRDBMSごとに方言があるので結構辛い。マニュアル片手に調べるのもいろいろと面倒くさかったのでRailsのmigrationの仕組みを使おうと考え、たどり着いたのが、standalone-migrations gemの利用でした。

github.com

使い方

gemのインストール

まずはgemをインストール。

$ gem install standalone-migrations

今回使ったのは5.2.6というバージョンでした。

$ gem list | grep standalone
standalone_migrations (5.2.6)
$

Rakefile作成

その後、Rakefileをカレントディレクトリ直下に作ります。

require 'standalone_migrations'
StandaloneMigrations::Tasks.load_tasks

migrationファイルの作成

次にdb/migrate/以下にテーブルを作成したりカラムを追加したりするmigrationファイルを作ります。今回はテーブルを作りたかったのでdb/migrate/001_create_tasks.rbというファイルを作り、中身を次のようにします。

class CreateTasks < ActiveRecord::Migration[4.2]
  def change
    create_table :tasks do |t|
      t.string :subject
      t.date :deadLine
      t.boolean :hasDone
    end
  end
end

ActiveRecord::Migration[4.2]のようにバージョン番号を入れる必要があります。入れないと実行時に

Directly inheriting from ActiveRecord::Migration is not supported. Please specify the Rails release the migration was written for:

というエラーメッセージが出力されてmigrationがうまく実行できません。

設定ファイル

最後に設定ファイルをdb/config.ymlに記します。ここではmacOSで動作確認するためだけにSQLite3の設定例を記していますが、お好きなRDBMSの設定をしてください。

development:
  adapter: sqlite3
  timeout: 5000
  database: db/development.sqlite3

実行

最後にコマンドを実行します。

$ rake db:migrate
== 1 CreateTasks: migrating ===================================================
-- adapter_name()
   -> 0.0000s
-- adapter_name()
   -> 0.0000s
-- adapter_name()
   -> 0.0000s
-- create_table(:tasks, {:id=>:integer})
   -> 0.0006s
== 1 CreateTasks: migrated (0.0007s) ==========================================
$

確認

SQLite3でテーブルができていることを確認します。

$ sqlite3 db/development.sqlite3
SQLite version 3.19.3 2017-06-27 16:48:08
Enter ".help" for usage hints.
sqlite> .schema
CREATE TABLE IF NOT EXISTS "schema_migrations" ("version" varchar NOT NULL PRIMARY KEY);
CREATE TABLE IF NOT EXISTS "ar_internal_metadata" ("key" varchar NOT NULL PRIMARY KEY, "value" varchar, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL);
CREATE TABLE IF NOT EXISTS "tasks" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "subject" varchar, "deadLine" date, "hasDone" boolean);
CREATE TABLE sqlite_sequence(name,seq);
sqlite>

今日はここまで。