DataMapperで比較的高速にidだけ取得する
dm-core-1.2.0の話です。
現在の検索条件でidだけ取得したい、、10000件くらい。って要望、よくあると思う。:fieldsで指定しても、モデルのインスタンスを作るため、sqlを直接実行した時にはかなわなかったりする。
なので、DataMapper::Collectionに次のようなメソッドを生やしている。
module DataMapper class Collection < LazyArray def select_statement(repository_name = :default) DataMapper.repository(repository_name).adapter.__send__(:select_statement, self.query) end def sql_select(repository_name = :default) return [] unless self.query.valid? sql, args = select_statement(repository_name) DataMapper.repository(repository_name).adapter.select(sql, *args) end end end
モデルのクラスメソッドにしないのは、クエリチェインするとクエリが壊れる恐れがある ため。
SQLとパラメータの取得方法についてはmonoさんの記事を参考しにした。
使い方
:fields と組み合わせて使う。 :fields で指定した要素が1つの場合はStructを作らずに値がそのまま入るので便利。
User.all(:name.like => 'a%').all(fields: [:id]).sql_select # => [1,2,3]