簡體   English   中英

如何以及在何處更新關聯模型的特定緩存計數器

[英]How and where update specific cached counter of associated models

我有兩個簡單的模型:

class Offer < ActiveRecord::Base
  belongs_to :offer_category

  scope :visible, -> { where(visible: true) }
end

class OfferCategory < ActiveRecord::Base
  has_many :offers

  def recount_visible_offers
    self.visible_offers_counter = offers.visible.count
    save
  end
end

我想緩存每個類別中可見商品的數量。 由於我只想統計可見的報價,所以我不能使用Rails counter_cache。 為此目的,我犯了一個方法recount_visible_offersOfferCategory ,其數量和節省我想要什么。 但是現在我被困在哪里以及如何稱呼它。

用過的方法需要處理所有改變計數器的情況

  1. 使用屬性visible = true創建新報價
  2. 提供更改其可見屬性
  3. 具有可見真實的報價被刪除
  4. 報價變更類別

現在,它由after_save和after_destroy回調處理,它們在相關類別實例上調用recount_visible_offers ,但是鑒於上述所有情況,它相當復雜並且容易出錯。 另一件事是,它很難測試。

所以我想以某種方式將其更改為更簡單。 我有一個想法:
self.recount_visible_offersOfferCategory方法,該方法在任何要約發生更改時(通過再次回調)重新計算所有類別上的所有計數器。 我知道它確實很強大,但是更簡單,我正在考慮在出現性能問題時就開始處理它,而不是現在就不那么頻繁地創建或更改新要約了,並且其中很多。

另一種方法是我正在調查的觸摸或關聯回調。

任何建議將不勝感激。 提前致謝。

獎勵問題:
您將在哪里測試基於報價變更類別計數器的正確重新計數? 我不確定它屬於單元測試,因為它涉及2個類一起工作。 另一方面,鑒於我想測試上述所有情況,因此功能測試似乎太繁瑣了。

我會這樣設置:

編輯:這包括一種跟蹤以前關聯的商品類別的技巧,因此可以調整新舊計數器的緩存字段。 我還使它使用“更改”方法使其僅在需要時使用。

class Offer
  belongs_to :offer_category
  scope :visible, -> { where(visible: true) }
  attr_accessor :previous_offer_category_id

  before_update :store_previous_offer_category_id
  after_save :update_offer_category_visible_offers_counters
  after_destroy :update_offer_category_visible_offers_counters    

  def store_previous_offer_category_id
    if self.changes["offer_category_id"]
      self.previous_offer_category_id = self.changes["offer_category_id"][0]
    end
  end

  def update_offer_category_visible_offers_counter
    if self.previous_offer_category_id && self.previous_offer_category_id != self.offer_category_id
      OfferCategory.find(self.previous_offer_category_id).update_visible_offers_counter
    end
    self.offer_category.update_visible_offers_counter
  end
end

class OfferCategory
  has_many :offers

  def set_visible_offers_counter
    self.visible_offers_counter = self.offers.visible.count
  end

  def update_visible_offers_counter
    self.set_visible_offers_counter
    self.save
  end

end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM