Rails の Migration で MySQL の型を指定する
たとえば、こんな感じの 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 を見ると分かるように coke
が char(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,
...
うまくいったらしい。