[英]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_offers
上OfferCategory
,其數量和節省我想要什么。 但是現在我被困在哪里以及如何稱呼它。
用過的方法需要處理所有改變計數器的情況
現在,它由after_save和after_destroy回調處理,它們在相關類別實例上調用recount_visible_offers
,但是鑒於上述所有情況,它相當復雜並且容易出錯。 另一件事是,它很難測試。
所以我想以某種方式將其更改為更簡單。 我有一個想法:
在self.recount_visible_offers
上OfferCategory
方法,該方法在任何要約發生更改時(通過再次回調)重新計算所有類別上的所有計數器。 我知道它確實很強大,但是更簡單,我正在考慮在出現性能問題時就開始處理它,而不是現在就不那么頻繁地創建或更改新要約了,並且其中很多。
另一種方法是我正在調查的觸摸或關聯回調。
任何建議將不勝感激。 提前致謝。
獎勵問題:
您將在哪里測試基於報價變更類別計數器的正確重新計數? 我不確定它屬於單元測試,因為它涉及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.