最近MariaDBにもバンドルされて手軽に使えるようになったMroongaですが、Railsから使う場合、テーブル定義はもちろんmigrationファイルに書きたくなると思います。
その記述方法について色々試行錯誤した結果、これがいいかな、という形に落ち着いたので、紹介します。
なお、ここで紹介するやり方はRails4.0.0で実装された機能(reversible)を使用しているため、3以前では動作しません。悪しからず。
試行錯誤した理由
-
Mroongaでは
FULLTEXT INDEX
が必要です。- Railsのmigrationファイルの記法では
FULLTEXT INDEX
の作成が用意されていないため、SQLで記述する必要があります。
- Railsのmigrationファイルの記法では
-
Tokenizer等を指定するためにテーブル/カラム/インデックスのコメントを使用します。
- Railsのmigrationファイルでは、カラム/インデックスにコメントをつけることが出来ません。
- migration_commentsというgemもありますが、これはカラムのみに対応していてインデックスにはつけられませんでした。
これらをSQLでどう書くかが試行錯誤のポイントでした。
Railsのmigrationファイルへの書き方
まずは、通常通りgenerateします。
ここでは 以下のコマンドでモデルクラスごと作成しました。
$ rails g model album code:string title:text artist_name:text
くだんのコメントは、reversibleを使って以下のように書きます。
(reversible機能についてはこのページが分かりやすいと思いました)
class CreateUsers < ActiveRecord::Migration
def change
create_table :album s, options: 'ENGINE=Mroonga COMMENT="default_tokenizer=TokenMecab"' do |t|
t.string :code
t.text :title
t.text :artist_name
t.timestamps
end
reversible do |dir|
dir.up do
execute 'ALTER TABLE albums MODIFY artist_name TEXT COMMENT \'flags "COLUMN_SCALAR|COMPRESS_ZLIB"\''
execute 'CREATE FULLTEXT INDEX `idx_albums_title` ON albums(title) COMMENT \'parser "TokenBigram", normalizer "NormalizerAuto"\''
execute 'CREATE FULLTEXT INDEX `idx_albums_artist_name` ON albums(artist_name) COMMENT \'parser "TokenBigram", normalizer "NormalizerAuto"\''
end
dir.down do
execute 'ALTER TABLE albums MODIFY artist_name TEXT COMMENT \'\''
execute 'DROP INDEX `idx_albums_title` ON albums'
execute 'DROP INDEX `idx_albums_artist_name` ON albums'
end
end
end
end
ALTER TABLE
コマンドとCREATE FULLTEXT INDEX
コマンドで、それぞれカラムとインデックスへのコメントを挿入しています。
作ったカラムを直後にALTER TABLE
している点がDRYらしくなくて気持ち悪いですが、今の所、このやり方が一番シンプルじゃないでしょうか。
生成されるテーブル
rake db:migrate
で生成されるテーブルに対してCREATE TABLE
すると、以下のような出力となります。
CREATE TABLE `albums` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`code` varchar(255) DEFAULT NULL,
`title` text DEFAULT NULL,
`artist_name` text DEFAULT NULL COMMENT 'flags "COLUMN_SCALAR|COMPRESS_ZLIB"',
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `idx_albums_title` (`title`) COMMENT 'parser "TokenBigram", normalizer "NormalizerAuto"',
FULLTEXT KEY `idx_albums_artist_name` (`artist_name`) COMMENT 'parser "TokenBigram", normalizer "NormalizerAuto"'
) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='default_tokenizer=TokenMecab'
期待通りのテーブルとなっている事が確認できるかと思います。
ちなみに…
RailsでGroongaを使いたい場合、Rroongaという選択肢もあります。
MySQLの機能(レプリケーションや、いわゆるテーブル間のリレーション)が必要なければ、こっちもお勧めです。