counter_cache в наследовании одной таблицы - PullRequest
6 голосов
/ 20 октября 2010

Мне интересно, будет ли counter_cache работать при наследовании одной таблицы.

Для этих моделей:

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

Какой?Я предполагаю 3-й, но я хочу еще 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 ]

10 голосов
/ 19 июля 2013

Просто столкнулся с той же ситуацией, и у меня это сработало, как вы ожидали (число 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

Вот и все! всякий раз, когда вы создаете вопрос, он увеличивает счетчик. Проверено на рельсах 3.2!

4 голосов
/ 23 октября 2010

Просматривая исходный код, в котором реализован ": 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
...