読者です 読者をやめる 読者になる 読者になる

DataMapper-1.2.0 + Kaminiari-0.14.1 でORをつかうクエリのtotal_countが動かない

具体的には次の部分が動かない

module Kaminari
  module DataMapperCollectionMethods
    def total_count #:nodoc:
      model.count(query.options.except(:limit, :offset, :order))
    end
  end
end

なんで?

試してみた。

class User
  include DataMapper::Resource

  property :id, Serial
  property :name, String
end

User.all(:name.like => "%hoge%").count
# => SELECT COUNT(*) FROM `users` WHERE `NAME` LIKE '%hoge%' ORDER BY `ID`
User.count(User.all(:name.like => "%hoge%").query.options)
# => SELECT COUNT(*) FROM `users` WHERE `NAME` LIKE '%hoge%' ORDER BY `ID`
(User.all(:name.like=> "%hoge%") + User.all(:name.like=> "%foo%")).count
# => SELECT COUNT(*) FROM `users` WHERE (`NAME` LIKE '%hoge%' OR `NAME` LIKE '%foo%') ORDER BY `ID`
User.count((User.all(:name.like=> "%hoge%") + User.all(:name.like=> "%foo%")).query.options)
# => SELECT COUNT(*) FROM `users` # これは、、

User.all(/ ORな条件 /) を書くことができないからUser.count(/ ORな条件 /) を書くこともできない?

モンキーパッチ

all.countを使えるようにすればよい。内部構造に依存しているので変更に弱い

module Kaminari
  module DataMapperCollectionMethods
    def total_count #:nodoc:
      all.tap { |a|
        query = a.query
        query.instance_variable_set(:@options, query.options.except(:limit, :offset, :order))
        query.instance_variable_set(:@limit, nil)
        query.instance_variable_set(:@offset, 0)
        query.instance_variable_set(:@order, query.model.default_order(query.repository.name))
      }.count
    end
  end
end