Railsからbigintを使用する時の注意点
idとかの AUTO_INCREMENTのカラムをbigintで使用している時、特に32bitを超える数値の時(自分のPCは32bitマシン)は明らかに挙動がおかしい。
例えば
id | bigint |
title | text |
body | text |
というテーブルがあり
alter table posts auto_increment = 100000000000000;
と設定し
post = Post.new post.title = "aaa" post.body = "bbb" post.save!
とした場合、MySQL C API の関数 mysql_insert_id()を実行します。
この関数は、直近の INSERT クエリにより AUTO_INCREMENT カラム用に生成さ
れたIDを取得します。が、mysql_insert_id() の返り値の型を long 型に変換します。
AUTO_INCREMENT カラムが BIGINT 型である場合、返される型は不正確になります。
なので、
redirect_to :action=>:show,id=>post
saveのあとに詳細ページへリダイレクトすると、modelのidの数値が不正なのでRecodeNotFoundとなります。
解決方法は
module ActiveRecord module ConnectionAdapters class MysqlAdapter < AbstractAdapter def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc: execute(sql, name = nil) id_value || @connection.query("SELECT LAST_INSERT_ID();").fetch_row()[0].to_i #id_value || @connection.insert_id end end end end
をenviroment.rbとかに書けばOK!
いや〜これで軽く半日はハマった^^;
でも、これは他の言語でも同じ現象起こしそうだ・・・