ActiveRecordでのdistinctについて
- あるModelから、
- user.idで抽出し、
- field_nameでDistinctしたレコードを、
- created_atの降順で、
- 5つ欲しかった
ので、以下のように実装してみた。
models = SomeModel.find(:all, :select => "distinct field_name", :limit => 5, :order => "created_at desc", :conditions => ["user_id = ?", user.id])
ローカル環境(MySQL)では、こいつでもまあ良かったのだが、
公私共にお世話になっているHerokuではPostgresqlを使っている様子で、
Distinct の文法が若干異なるのでエラーを出された。
なんで、以下のようにして解決した。
if connection.supports_count_distinct? select_str = connection.distinct(:field_name, "created_at desc") models = SomeModel.find(:all, :select => select_str, :limit => 5, :conditions => ["user_id = ?", user.id]) end
細かい点
connection.supports_count_distinct?
こいつは、各データベース用のアダプタでDistinctが実装されているか確認するメソッド。
connectionってのは、以下を参照のこと。
参考:
Ruby on Rails - ActiveRecord -
—
ありえるえりあ
connection.distinct(:field_name, "created_at desc")
こいつで、各データベースがDistinctを拡張しているので、
言われたとおりにデータを渡す。
というカンジ。
ついでに
なお、Distinctが実装されていない場合も考えて
以下の実装も追加した。
temp_models = SomeModel.find(:all, :order => "created_at desc", :conditions => ["user_id = ?", user.id]) models = temp_models.map{ |i| i }.uniq[0..5]
まとめ
最終的にはこんなカンジ。
class SomeModel < ActiveRecord::Base def self.recent(user) if connection.supports_count_distinct? select_str = connection.distinct(:field_name, "created_at desc") models = SomeModel.find(:all, :select => select_str, :limit => 5, :conditions => ["user_id = ?", user.id]) else temp_models = SomeModel.find(:all, :order => "created_at desc", :conditions => ["user_id = ?", user.id]) models = temp_models.map{ |i| i }.uniq[0..5] end end end