9 Stimmen

counter_cache mit Bedingungen

Ich weiß, dass ich Rückrufe verwenden kann, aber das sollte machbar sein. Ich habe lange gesucht und kein Ergebnis. Dies ist, was ich dachte, würde funktioniert haben.

def User < ActiveRecord::Base
  has_many :documents
  has_many :draft_docs     , :class_name => 'Document', :conditions => { :status => 'draft' }
  has_many :published_docs , :class_name => 'Document', :conditions => { :status => 'published' }
  has_many :private_docs   , :class_name => 'Document', :conditions => { :status => 'private' }
end

def Document < ActiveRecord::Base
  belongs_to :user      , :counter_cache => true
  belongs_to :user      , :inverse_of => :draft_docs    , :counter_cache => true
  belongs_to :user      , :inverse_of => :published_docs, :counter_cache => true
  belongs_to :user      , :inverse_of => :private_docs  , :counter_cache => true
end

Funktioniert nicht wie geplant. Wie Sie sehen können, wird documents_count anstelle von published_docs_count aktualisiert.

ruby-1.9.2-p180 :021 > User.reset_counters 2, :published_docs  User Load (0.4ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
   (0.7ms)  SELECT COUNT(*) FROM `documents` WHERE `documents`.`user_id` = 2 AND `documents`.`status` = 'published'
   (2.2ms)  UPDATE `users` SET `documents_count` = 233 WHERE `users`.`id` = 2
 => true

2voto

blablb Punkte 29

Das liegt daran, dass Sie für alle Assoziationen denselben Namen verwenden.

belongs_to :user, :counter_cache => true
belongs_to :user_doc, :class_name => "User", 
           :inverse_of => :draft_docs, :counter_cache => :draft_docs_count

Diese Funktionalität wird implementiert, indem ein Callback hinzugefügt wird, um die Anzahl zu erhöhen, und in Ihrem Fall ist das Ziel document.user da Sie für alles denselben Namen verwendet haben.

1voto

Harish Shetty Punkte 63187

Verwenden Sie die Gegen_Kultur gem.

  • Fügen Sie drei Spalten zu der users Tisch.

    add_column :users, :draft_documents_count, :integer, null: false, default: 0
    add_column :users, :published_documents_count, :integer, null: false, default: 0
    add_column :users, :private_documents_count, :integer, null: false, default: 0
  • Dekorieren Sie die Document Modell

    class Document
      counter_culture :user, :column_name => Proc.new do |doc|
        if %w(draft published private).include?(doc.status) 
          "{doc.status}_documents_count"
        end
      end    
    end
  • Führen Sie einen Befehl in der Konsole aus, um die Zählerstände für die aktuellen Zeilen zu ermitteln

    Document.counter_culture_fix_counts

Alte Antwort

Sie können den Namen der Zählerspalte angeben (außer true ) zum counter_cache Option.

class Document < ActiveRecord::Base
  belongs_to :user, :counter_cache => true
  belongs_to :user, :inverse_of => :draft_docs, 
                                   :counter_cache => :draft_docs_count
  belongs_to :user, :inverse_of => :published_docs, 
                                   :counter_cache => :published_docs_count
  belongs_to :user, :inverse_of => :private_docs, 
                                   :counter_cache => :private_docs_count
end

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X