named_scopeは賢い! しかし・・・・

named_scope を使い少しハマリました ^^);
次のような model を作り

class User < ActiveRecord::Base
  named_scope :male, :conditions => {:sex => 'M'}
  named_scope :unique_attr, :select => "distinct age,sex"
end

console で

% ./script/console
>> User.all
=> [#<User id: 1, name: "山田太郎", age: 35, sex: "M", created_at: nil, updated_at: nil>, #<User id: 2, name: "山田次郎", age: 25, sex: "M", created_at: nil, updated_at: nil>, #<User id: 3, name: "川田花子", age: 25, sex: "F", created_at: nil, updated_at: nil>]
>> User.male
=> [#<User id: 1, name: "山田太郎", age: 35, sex: "M", created_at: nil, updated_at: nil>, #<User id: 2, name: "山田次郎", age: 25, sex: "M", created_at: nil, updated_at: nil>]
>> User.male.size
=> 2

この時実行されたSQLを見ると

SELECT * FROM "users"
SELECT * FROM "users" WHERE ("users"."sex" = 'M')
SELECT count(*) AS count_all FROM "users" WHERE ("users"."sex" = 'M')

最後のSQLを見て下さい。なんと User.male の実行結果の配列の size を求めるのではなく、 SELECT COUNT(*) に置き換えています! 賢い \(^O^)/


しかし、

% ./script/console
>> User.unique_attr
=> [#<User age: 25, sex: "F">, #<User age: 25, sex: "M">, #<User age: 35, sex: "M">]
>> User.unique_attr.count
ActiveRecord::StatementInvalid: SQLite3::SQLException: wrong number of arguments to function count():
 SELECT count(distinct age,sex) AS count_distinct_age_sex FROM "users" 
 ...
 ...

と DISTINCTがあるのに COUNT を取ろうとしてエラーになってしまいます ^^);

エラーにならないようにするには

% ./script/console
User.unique_attr.length
=> 3

で 出来ます。


ちなみに、Rails2.1.2 ではエラーは発生しませんでした。また、RDBMySQLの場合は上のエラーにはならず期待される結果がでますが、標準SQL規格ではエラーのようです。