Rails+CのMySQLアダプタで、idにbigintを使う場合の注意
はまった。まじではまった。
RailsでMySQL使うときはMySQLアダプタ(ドライバ?)が必要だけど、これRuby版であれば問題ないんだが、
C版だとbigintの値(厳密には、integerを超える値)が強制的にintegerに変換されてしまう。
どういう場面かというと、DBに新しい行をINSERTした後、モデル経由でidを取得する場合。
※ちなみにidは当然auto_increment
#idは、11111111111111111のbigint。 @model.save @model.id => -2074054200
ええ!!
当然C版のほうが圧倒的に早いから使うんだけど、これだと使えない。
いろいろ調べてみた。
http://d.hatena.ne.jp/ryu00026/20070320/1174412910
こればっちり。いやー非常にたすかった。
ただし、Rails2系の場合は、オーバーライドするメソッドが違うので注意。
で、対処には、せっかくだからinitialiserを利用すると、以下のようになる。
$RAILS_ROOT/config/initializers/mysql_adaptor_hack.rb
# # MySQLで、idにbigintを利用する場合のハック # module ActiveRecord module ConnectionAdapters class MysqlAdapter < AbstractAdapter def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc: super sql, name id_value || @connection.query("SELECT LAST_INSERT_ID();").fetch_row()[0].to_i #id_value || @connection.insert_id end end end end
ちなみに割り込みでINSERTされたらどうすんの?ってことで、また調べてみた。
http://blog.tofu-kun.org/071206185929.php
http://blogs.wankuma.com/rti/archive/2007/09/05/94106.aspx
どうやら同一セッション内で最後にINSERTした値を取得するようなので、大丈夫??