migrateとARとMySQL

migrationの設定とARの関係。
ARとMySQLの関係。
をよく分かってないことに気づいたのでちょっと調べる事に。


migrationの定義はこんな感じ

class CreateHoge < ActiveRecord::Migration
def self.up
create_table :hoge do |t|
t.column :i1 , :integer , :null => false
t.column :i2 , :integer , :default => 0 , :null => false
t.column :i3 , :integer , :null => true
t.column :i4 , :integer , :default => 0 , :null => true
t.column :s1 , :string , :null => false
t.column :s2 , :string , :default => "" , :null => false
t.column :s3 , :string , :null => true
t.column :s4 , :string , :default => "" , :null => true
t.column :t1 , :text , :null => false
t.column :t2 , :text , :default => "" , :null => false
t.column :t3 , :text , :null => true
t.column :t4 , :text , :default => "" , :null => true
end
end

def self.down
drop_table :hoge
end
end

で、newして見る。

ruby script/console
>>hoge = Hoge.new
=> #nil, "s3"=>nil, "i4"=>0, "s4"=>"", "t1"=>"", "t2"=>"", "s1"=>"", i1"=>nil, "t3"=>nil, "s2"=>"", "i2"=>0, "i3"=>nil}>
>> hoge.save


save。例外が起こる。

[4;35;1mSQL (0.000000) [0m [0mMysql::Error: #23000Column 'i1' cannot be null: INSERT INTO hoge (`i4`, `s3`, `s4`, `i1`, `s1`, `i2`, `s2`, `i3`) VALUES(0, NULL, '', NULL, '', 0, '', NULL) [0m


i1にはNullを入れられませんよ、との事。そりゃそうだ。なので値を入れて再度save。

hoge.i1 = 1
hoge.save


今度は出来た。

[4;35;1mSQL (0.000000) [0m [0mINSERT INTO advertises (`i4`, `s3`, `s4`, `i1`, `s1`, `i2`, `s2`, `i3`) VALUES(0, NULL, '', 1, '', 0, '', NULL)[0m


DBに入っている値はこんな感じ。

id i1 i2 i3 i4 s1 s2 s3 s4 t1 t2 t3 t4
1 1 0 NULL 0 NULL NULL NULL

まとめ

データ型 null デフォルト AR初期値 insert値
:int false 未定義 nil エラー
:int false 0 0 0
:int true 未定義 nil null
:int true 0 0 0
:string false 未定義 "" ""
:string false "" "" ""
:string true 未定義 nil null
:string true "" "" ""
:text false 未定義 nil ""
:text false "" "" ""
:text true 未定義 nil null
:text true "" "" null

追記

表をちょっと修正。

雑感

  • ARでは値がnilの場合にはinsert文には出てこない。
  • stringとtextについてはnull不許可でDefault値を未設定でも空文字列が自動で入る。一方で、AR上ではnilが格納される。これがちょっと分かりにくい。MySQLで実行してもエラーになる事はないが、Field 't1' doesn't have a default valueという警告が出る。
  • stringとtextで実は若干挙動が違う。なんだこりゃ。

もうちょっと詳細に調べた方が良いのかも…。