おもしろwebサービス開発日記

Ruby や Rails を中心に、web技術について書いています

いつの間にかvalidates_uniqueness_ofの仕様が変わっている件

別ブログに書いてたものをまとめてみました。
case_sensitiveで大文字と小文字を区別・・・できない - おもしろWEBサービス開発日記のrailsメモ - railsグループ

昔の仕様

これまで、mysqlを使用しているとき、値の唯一性をチェックするvalidates_uniqueness_ofメソッドの:case_sensitiveはtrueにしても大文字小文字の区別はつきませんでした。理由はmysqlがデフォルトでは大文字小文字を区別していないからで、回避方法としては該当テーブルのmigrationファイルに

execute("ALTER TABLE users MODIFY login varchar(255) BINARY NOT NULL")

のように書いてカラムにBINARY性質をつけるか、SELECT文中にBINARYをつけてやる必要があります。

最近の仕様

これまで、大文字小文字を区別したいカラムは上記のようにmigrationファイルを修正して対処していたのですが、いつのころからかrails側で対応してくれるようになっていたようです。

rails2.3.4で

class User < ActiveRecord::Base
  validates_uniqueness_of :name, :case_sensitive => true
end

のようにしてUser.saveすると

SELECT `users`.id FROM `users` WHERE (`users`.`name` = BINARY 'HOGE')

上記のように、BINARYがついたSQL文が発行されます。つまり、mysqlを使ってるとか特に気にせずに大文字小文字が区別できるようになっています。

いつから?

たぶんvalidates_uniqueness_ofの仕様が少し変わった(:case_sensitiveのデフォルトがfalseからtrueになった)2.2.0からだと思いますが確認してません。だれかご存じの方いたら教えてください><