yo_waka's blog

418 I'm a teapot

ActiveRecordのマイグレーションでMySQLのunsignedな数値タイプを指定できるGemライブラリ作った

今の会社でRailsを使うようになって、いわゆるマイグレーションの仕組み超便利。

なんですが、MySQLを使っているのにidや数値にunsignedを指定できないのどうなんだろう。
他のDBはサポートしてないからいらないよねっていうのも分かるんですが、せっかくアダプタが分けられてるならサポートしてもいいんじゃないかな。
ということで、ActiveRecordの勉強がてらマイグレーションでintegerなカラムに"unsigned"を指定できるGemライブラリを作ってみました。

github/activerecord-mysql-unsigned

ついでに初めてのRubyGemsで公開もしてみた。
rubygems/activerecord-mysql-unsigned

ActiveRecord3.2以降と4で動作確認しています。

使い方はGemfileに書いて、マイグレーションファイルで「unsigned: true」をオプションに指定するだけ。

class CreateUsersTable < ActiveRecord::Migration
  def self.change
    create_table :users, force: true do |t|
      t.string  :name, null: false
      t.integer :age,  null: false, unsigned: true
    end
  end
end

既存のテーブルの主キーや数値カラムを置き換えるのが主目的なので、change_columnでも使えます。
このためにv3.2でauto_incrementをオプションで指定できるようにもしてあったり。

class ChangeColumnToUsersTable < ActiveRecord::Migration
  def self.change
    change_column :users, :id,  :integer, null: false, unsigned: true, auto_increment: true # 主キー
    change_column :users, :age, :integer, null: false, unsigned: false
  end
end

v3.2とv4.0の両方対応させるためにActiveRecordのソース読みましたが、中のクラス構造や挙動が結構変わってるんですねー。
v3.2だとunsignedな数値カラムにマイナス値を入れると0が保存される。v4.0だとActiveRecord::StatementInvalidエラーにしてくれる。
v4.0の方が圧倒的に見通しもいいしソースも綺麗。カラムのマイグレーションにもcollationやextraオプションを指定できたりいろいろ便利そうな機能を発見しました。
ウチのサービスも早く4.0にしたいなーっ。。。