Ruby-on-rails Rails 中页面视图的简单命中计数器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4815713/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 00:12:52  来源:igfitidea点击:

simple hit counter for page views in rails

ruby-on-railsruby-on-rails-3google-analyticsgoogle-apicounter

提问by holden

I've found several solutions for this problem, for example railstat from this post:

我为这个问题找到了几个解决方案,例如这篇文章中的 railstat:

Page views in Rails

Rails 中的页面浏览量

I have a bunch of articles and reviews which I would like a hit counter filtered by unique IPs. Exactly like Stackoverflow does for this post. But I don't really care for such a solution as railstat when google analytics is already doing this for me and including a whole lot of code, keeping track of unique IPs, etc.. My present thinking is to use Garb or some other Analytics plugin to pull the pages stats if they are older than say 12 hours updating some table, but I also need a cache_column.

我有一堆文章和评论,我想要一个按独特 IP 过滤的点击计数器。就像 Stackoverflow 在这篇文章中所做的一样。但是当谷歌分析已经为我做这件事并包括大量代码、跟踪唯一 IP 等时,我并不真正关心像 railstat 这样的解决方案。我目前的想法是使用 Garb 或其他一些分析如果页面更新时间超过 12 小时,则可以使用插件来提取页面统计信息,但我还需要一个 cache_column。

I'm assuming you can pull stats from Analytics for a particular page and that they update their stats every 12 hours?

我假设您可以从 Analytics 中提取特定页面的统计数据,并且他们每 12 小时更新一次统计数据?

I'm wondering if there are any reasons why this would be a bad idea, or if someone has a better solution?

我想知道是否有任何原因为什么这会是一个坏主意,或者是否有人有更好的解决方案?

Thanks

谢谢

回答by johnmcaliley

UPDATE

更新

The code in this answer was used as a basis for http://github.com/charlotte-ruby/impressionistTry it out

此答案中的代码用作http://github.com/charlotte-ruby/impressionist的基础 试试看



It would probably take you less time to code this into your app then it would to pull the data from Analytics using their API. This data would most likely be more accurate and you would not have to rely an an external dependancy.. also you would have the stats in realtime instead of waiting 12 hours on Analytics data. request.remote_ipworks pretty well. Here is a solution using polymorphism. Please note that this code is untested, but it should be close.

将其编码到您的应用程序中可能会花费更少的时间,然后使用他们的 API 从 Analytics 中提取数据。这些数据很可能会更准确,而且您不必依赖外部依赖......而且您将获得实时统计数据,而不是等待 12 小时的 Analytics 数据。 request.remote_ip效果很好。这是使用多态的解决方案。请注意,此代码未经测试,但应该很接近。

Create a new model/migration to store your page views (impressions):

创建一个新模型/迁移来存储您的页面浏览量(印象数):

class Impressions < ActiveRecord::Base
  belongs_to :impressionable, :polymorphic=>true 
end

class CreateImpressionsTable < ActiveRecord::Migration
  def self.up
    create_table :impressions, :force => true do |t|
      t.string :impressionable_type
      t.integer :impressionable_id
      t.integer :user_id
      t.string :ip_address
      t.timestamps
    end
  end

  def self.down
    drop_table :impressions
  end
end

Add a line to your Article model for the association and add a method to return the impression count:

在您的文章模型中为关联添加一行,并添加一个方法来返回展示次数:

class Article < ActiveRecord::Base
  has_many :impressions, :as=>:impressionable

  def impression_count
    impressions.size
  end

  def unique_impression_count
    # impressions.group(:ip_address).size gives => {'127.0.0.1'=>9, '0.0.0.0'=>1}
    # so getting keys from the hash and calculating the number of keys
    impressions.group(:ip_address).size.keys.length #TESTED
  end
end

Create a before_filter for articles_controller on the show action:

在 show 动作上为articles_controller 创建一个before_filter:

before_filter :log_impression, :only=> [:show]

def log_impression
  @article = Article.find(params[:id])
  # this assumes you have a current_user method in your authentication system
  @article.impressions.create(ip_address: request.remote_ip,user_id:current_user.id)
end

Then you just call the unique_impression_count in your view

然后你只需在你的视图中调用 unique_impression_count

<%[email protected]_impression_count %>

If you are using this on a bunch of models, you may want to DRY it up. Put the before_filter def in application_controller and use something dynamic like:

如果你在一堆模型上使用它,你可能想把它弄干。将 before_filter def 放在 application_controller 中并使用动态的东西,例如:

impressionable_class = controller_name.gsub("Controller","").constantize
impressionable_instance = impressionable_class.find(params[:id])
impressionable_instance.impressions.create(ip_address:request.remote_ip,user_id:current_user.id)

And also move the code in the Article model to a module that will be included in ActiveRecord::Base. You could put the send include in a config/initializer.. or if you want to get crazy, just turn the whole thing into a rails engine, so you can reuse on other apps.

并且还将文章模型中的代码移动到将包含在 ActiveRecord::Base 中的模块中。您可以将发送包含放在配置/初始化程序中...或者如果您想发疯,只需将整个内容转换为 rails 引擎,以便您可以在其他应用程序上重用。

module Impressionable
  def is_impressionable
    has_many :impressions, :as=>:impressionable
    include InstanceMethods
  end
  module InstanceMethods
    def impression_count
      impressions.size
    end

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

ActiveRecord::Base.extend Impressionable