代码之家  ›  专栏  ›  技术社区  ›  PeterWong

单表继承中的计数器缓存

  •  6
  • PeterWong  · 技术社区  · 14 年前

    我想知道计数器缓存是否可以在单表继承中工作。

    对于这些型号:

    class User
      has_many :questions
    end
    
    class Question
      belongs_to :user, :counter_cache => true
    end
    
    class SimpleQuestion < Question
    end
    class ComplexQuestion < Question
    end
    

    那么下面的计数器会工作吗?

    create_table(:users) do |t|
      t.integer :questions_count
      t.integer :simple_questions_count
      t.integer :complex_questions_count
    end
    
    1. 它们都能工作
    2. 它们都不起作用
    3. 只有 questions_count 工作
    4. 只有 simple_questions_count complex_questions_count

    哪一个?我猜是第三个,但我还想要4个。如果不是4,我怎么让4工作?

    ===更新===

    下面是一个例子:

    id, user_id, question_content, type
    1, 3, something, SimpleQuestion
    2, 3, something, SimpleQuestion
    3, 3, something, ComplexQuestion
    

    所以现在我想:

    user.questions_count # => 3
    user.simple_questions_count # => 2
    user.complex_questions_count # => 1
    

    我的问题是,什么是 :counter_cache => true 是否可以应用于单表继承?

    2 回复  |  直到 11 年前
        1
  •  4
  •   Ben Lee    14 年前

    纵观实现了“:counter_cache”的源代码,它看起来不支持您需要的那种计数。幸运的是,你很容易在这里滚自己的车。只需更新问题以手动跟踪计数,如下所示:

    class Question
      belongs_to :user
    
      after_create :increment_counts
      before_destroy :decrement_counts
    
      protected
    
      def increment_counts
        User.increment_counter :questions_count, user_id
        User.increment_counter "#{type.pluralize.underscore}_count", user_id
      end
    
      def decrement_counts
        User.decrement_counter :questions_count, user_id
        User.decrement_counter "#{type.pluralize.underscore}_count", user_id
      end
    end
    
        2
  •  10
  •   prikha    11 年前

    刚刚面对同样的情况,它为我工作,正如你所期望的(数字4):

    看,像这样修改代码,这样子类就可以覆盖父类的行为:

    class User
      has_many :questions
    end
    
    class Question
      belongs_to :user
    end
    
    class SimpleQuestion < Question
      belongs_to :user, :counter_cache => true
    end
    class ComplexQuestion < Question
      belongs_to :user, :counter_cache => true
    end
    

    并添加 complex_questions_count simple_questions_count 列到你的 User

    就是这样!每当您创建一个“是”问题时,它都会增加适当的计数器。在Rails 3.2上测试过!