Rails+CのMySQLアダプタで、idにbigintを使う場合の注意

はまった。まじではまった。
RailsMySQL使うときは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した値を取得するようなので、大丈夫??