首页 > 解决方案 > 带条件的计数器缓存

问题描述

我在我的应用程序中添加了一项功能,可以在其中计算两个特定页面上的唯一身份访问者。这是我的设置:

class Impression < ApplicationRecord
  belongs_to :impressionable, :polymorphic => true, counter_cache: :impressions_count
end

class Product < ApplicationRecord
  has_many :impressions, :as=>:impressionable

  def impression_count
    impressions.size
  end

  def unique_impression_count
    impressions.group(:ip_address).size.keys.length
  end
end

class Variant < ApplicationRecord
  has_many :impressions, :as=>:impressionable

  def impression_count
    impressions.size
  end

  def unique_impression_count
    impressions.group(:ip_address).size.keys.length
  end
end

class ProductsController < ApplicationController
  before_action :log_impression, :only=> [:show]


  def log_impression
    @product.impressions.find_or_create_by(ip_address: request.remote_ip)
  end
end


class VariantsController < ApplicationController
  before_action :log_impression, :only=> [:show]


  def log_impression
    @variant.impressions.find_or_create_by(ip_address: request.remote_ip)
  end
end

一切正常。每次我访问特定的展示页面时,都会在数据库中创建一个印象。

现在我正在尝试实现一个观看次数最多的产品/变体循环。首先,我将两个数组(产品和变体)组合在一起,然后按impressions_count. 我t.integer :impressions_count为产品模型和变体模型添加了一个列。而且我每次都在 . 中更新列counter_cache: :impressions_countImpression Model正如您在上面的设置中看到的那样。

inventory = current_user.store.products.order('impressions_count DESC').limit(5) | current_user.store.variants.order('impressions_count DESC').limit(5)
@top_products =  inventory.sort_by { |st| st['impressions_count'].to_i }.reverse

一切正常,但我唯一注意到的是,当我在视图中执行此操作时:

 <% @top_products.each do |product| %>
   <%= product.unique_impression_count %> 
 <% end %>

上面的循环显示 1 个视图!我认为这是正确的,因为我正在计算每个 IP 的独特视图。

另一方面,该impressions_count列显示不同的数字并弄乱了 @top_products = inventory.sort_by { |st| st['impressions_count'].to_i }.reverse方法。

impressions_count每次我访问显示页面时,该列都会更新。

有没有一种方法可以添加唯一条件,counter_cache: :impressions_count以便仅当访问者来自另一个 IP 时才更新列?

标签: ruby-on-railsrubyruby-on-rails-5

解决方案


推荐阅读