6

Zastanawiam się, czy counter_cache działałby w dziedziczeniu z jednej tabeli.counter_cache w dziedziczeniu pojedynczego stołu

Dla tych modeli:

class User 
    has_many :questions 
end 

class Question 
    belongs_to :user, :counter_cache => true 
end 

class SimpleQuestion < Question 
end 
class ComplexQuestion < Question 
end 

Więc będzie działać następujące liczniki?

create_table(:users) do |t| 
    t.integer :questions_count 
    t.integer :simple_questions_count 
    t.integer :complex_questions_count 
end 
  1. Wszystkie z nich działają
  2. Żaden z nich nie działa
  3. Tylko questions_count pracy
  4. Tylko simple_questions_count i complex_questions_count

który? Zgaduję 3, ale chcę jeszcze 4. Jeśli to nie 4, jak mam zrobić 4 prace?

=== UPDATE ===

Oto przykład:

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

Więc teraz chcę:

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

Moje pytanie brzmi, co jest podstawowym i zachowanie :counter_cache => true czy można ubiegać się o dziedziczenie z jednego stołu?

+0

Czy próbujesz mieć 'simple_questions_count' i' complex_questions_count' zwracają ten sam numer? A może liczyć się na podstawie innych pól w tabeli pytań (np. Użytkownik przesyła pytanie proste lub złożone)? – erskingardner

+0

'SimpleQuestion' i' ComplexQuestion' są podklasami 'Pytanie', mającymi różne' type' w tej samej tabeli. Może podam przykład. – PeterWong

Odpowiedz

4

Przeglądając kod źródłowy, w którym zaimplementowano ": counter_cache", wygląda na to, że nie obsługuje on takiego rodzaju zliczania, jakiego potrzebujesz. Na szczęście łatwo jest tu przetasować własne. Wystarczy zaktualizować Pytanie ręcznie śledzić liczbę, tak:

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 
+0

Nie powinienem używać 'after_create' zamiast' after_save'? Masz na myśli, że 'counter_cache' nie zadziałałoby na' questions_count'? Co powiesz na 'simple_questions_count' i' complex_questions_count'? Będą działać na 'belongs_to: user,: counter_cache => true'? – PeterWong

+0

Tak, masz rację. Powinien to być afer_create, a nie after_save. Tylko literówka z mojej strony. Dla question_count, "counter_cache => true" będzie działać, ale myślę, że jeśli będziesz miał ręczne kontrłaty zwrotne tak czy inaczej, równie dobrze możesz umieścić tam logikę question_count.Dla simple_questions_count i complex_questions_count, Rails obecnie nie oferuje wbudowanego rozwiązania - do tego służą ręczne wywołania zwrotne. –

+0

Zaktualizowałem fragment kodu powyżej, by naprawić literówkę after_create. –

10

właśnie w obliczu takiej samej sytuacji i to działało na mnie jak oczekiwano (num 4):

Look, zmodyfikować kod tak, tak że podklasy by przesłonić zachowanie rodziców:

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 

i dodać complex_questions_count i simple_questions_count kolumny do User

To! za każdym razem, gdy tworzysz pytanie, zwiększy ono właściwy licznik. Testowany na szynach 3.2!

+0

To działało dla mnie w Rails 4.1 –

Powiązane problemy