Rails の Migration で MySQL の型を指定する

Rails の Migration で MySQL の型を指定する

2008/02/07 8:37am

たとえば、こんな感じの Migration を考えてみる。

class CreatePepsi < ActiveRecord::Migration
  def self.up
    create_table :pepsies do |t|
      t.column :coke,       :string, :limit => 64
      t.column :jolt,       :integer
      t.column :created_at, :datetime
      t.column :updated_at, :datetime
    end
  end

  def self.down
    drop_table :addresses
  end
end

Rails 2.0 の sexy migration ではこんなふうにも書けるんだけど、個人的に馴染まないので今回はスルー。

class CreatePepsi < ActiveRecord::Migration
  def self.up
    create_table :pepsies do |t|
      t.string  :coke, :limit => 64
      t.integer :jolt
      t.timestamps
    end
  end

  def self.down
    drop_table :addresses
  end
end

rake db:migrate したときの CREATE TABLE はこうなる。

CREATE TABLE `pepsies` (
  `id` int(11) NOT NULL auto_increment,
  `coke` varchar(64) default NULL,
  `jolt` int(11) default NULL,
  `created_at` datetime default NULL,
  `updated_at` datetime default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

string は MySQL の VARCHAR に、integer は int になる。これを CHAR とか SMALLINT とかにできないか、というのが今回の話題。

CHAR とか SMALLINT とかにしてみる

結論からいえば、これでよい。

class CreatePepsi < ActiveRecord::Migration
  def self.up
    create_table :pepsies do |t|
      t.column :coke,       :CHAR, :limit => 64
      t.column :jolt,       :SMALLINT
      t.column :created_at, :datetime
      t.column :updated_at, :datetime
    end
  end

  def self.down
    drop_table :addresses
  end
end

本当に CHAR とか SMALLINT とかにしてみただけである(といっても Symbol になってるけど)。

CREATE TABLE はこうなる。

CREATE TABLE `pepsies` (
  `id` int(11) NOT NULL auto_increment,
  `coke` char(1) default NULL,
  `jolt` smallint(6) default NULL,
  `created_at` datetime default NULL,
  `updated_at` datetime default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

:limit が効かない

SQL を見ると分かるように cokechar(1) となってしまい、Migration で指定した :limit => 64 が効いていないようだ。

とりあえず素直に対応してみよう。

class CreatePepsi < ActiveRecord::Migration
  def self.up
    create_table :pepsies do |t|
      t.column :coke,       :"CHAR(64)"
      t.column :jolt,       :SMALLINT
...

:CHAR という指定を :"CHAR(64)" にしたわけだ(Ruby の Symbol リテラルでは :"…" や :'…' の形式で、任意のシンボルを定義することができる)。

再度、CREATE TABLE を確認。

CREATE TABLE `pepsies` (
  `id` int(11) NOT NULL auto_increment,
  `coke` char(64) default NULL,
  `jolt` smallint(6) default NULL,
...

うまくいったらしい。