2017-10-30 17 views
0

これは、この質問のフォローアップの一種です。Is overriding an ActiveRecord relation's count() method okay?基本的に私はページ付けをしたいと思っており、カウントは遅いので、キャッシュされたカウンタ属性でcount()を無効にしています。シングルトンメソッドと委譲メソッドが異なる動作をするのはなぜですか?

は私が持っている:

class CountDelegator < SimpleDelegator 
    def initialize(obj, total_count) 
    super(obj) 
    @total_count = total_count 
    end 

    def count 
    @total_count 
    end 
end 

class Parent 
    has_many :kids do 
    def chatty_with_singleton 
     resultset = where(:chatty => true) 
     def resultset.count 
     proxy_association.owner.chatty_kids_count 
     end 
     resultset 
    end 

    def chatty_with_delegation 
     resultset = where(:chatty => true) 
     CountDelegator.new(resultset, proxy_association.owner.chatty_kids_count) 
    end 
    end 
end 

p = Parent.first 

を今、私はp.kids.chatty_with_singleton.countまたはp.kids.chatty_with_delegation.countいずれかを実行したときに、私はキャッシュされ、カウントを使用しています。すばらしいです!しかし、異なる動作を以下:

# Uses the cached count 
p.kids.chatty_with_singleton(:order => "id desc").count 

# Does not use the cached count 
p.kids.chatty_with_delegation(:order => "id desc").count 

私は完全に混乱している - これらの2つの場合は実際には異なる動作をする理由私は知りません。 (はい、私はp.kids.chatty_with_singleton(:id => 0).countが間違った値を返し、私はそれで大丈夫であることを認識しています)

シングルトンの結果セットでメソッドを定義すると、その定義が支配的になるのに対して、委譲者はなぜですか?

+0

ちょうどそれを行う '.size'を使うことができます... – max

+0

http://work.stevegrossi.com/2015/04/25/how-to-count-with-activerecord/ – max

+0

これはありません'size()'と 'count()'の問題です。 'size()'と 'count()'の両方を委譲すると、 'p.chatty_kids_with_delegation.order(" id desc ")。size'はキャッシュされた属性を使うのではなく、COUNTクエリを実行します。 – Nate

答えて

0

belongs_toで提供される組み込みのcounter_cacheオプションを再実装しています。レールのデフォルト列を使用していない場合は、単にキャッシュの列も指定します。

counter_cacheを使用すると、COUNTを実行する代わりに、テーブルのキャッシュされた値が自動的に読み取られます。

+0

私はカウンタキャッシュを使っているとは思わない。 1つは、counter_cacheは一部のケース(例:チャット= trueの子供)にカウントされ、もう1つはデータベースのトリガーでカウンタを最新に保つことです(テーブルを時々更新しますRailsの外側にある)、Railsが列の値をバンプしようとしないようにします。しかし、カウンターキャッシュの実装方法を見て、それを盗もうとするかもしれません。 – Nate

関連する問題