`
huacnlee
  • 浏览: 9331 次
  • 性别: Icon_minigender_1
  • 来自: 成都
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Rails 插件 acts_as_views_count - Model访问量延迟统计

阅读更多

项目有很多时候需要进行统计单篇文章的访问次数,如文章、帖子、图片...
于是在表里面设计一个 views_count 字段作为计数器,然后查看页面的时候更新这个字段。

但为了提要效率,一般情况下我们都需要对 views_count 的写入数据库做一下延迟,存到缓存里面去,到了一定数量在更新数据库。

为了方便使用,我把之前的方式改写成了一个插件,第一次做 Rails 插件,比较简单

 

使用例子

Models

View: Source or Raw
1
2
3
4
5
6
7
8
class Post < ActiveRecord::Base
  acts_as_views_count
end

class Topic < ActiveRecord::Base
  # set delay save to db with 30
  acts_as_views_count :delay => 30
end

Controllers

View: Source or Raw
1
2
3
4
5
6
7
class PostsController < ApplicationController
  def show
    @post = Post.find(params[:id])
    # update views_count
    @post.update_views_count
  end
end

Views

View: Source or Raw
1
2
3
4
5
6
7
<div id="post_show">
  <h1><%= @post.title %></h1>
  <div class="info">
    <span><%= @post.views_count_s %> views</span>
    <span><%= @post.comments_count %> comments</span>
  </div>
</div>
分享到:
评论
7 楼 huacnlee 2010-01-18  
edisonlz 写道
huacnlee 写道
edisonlz 写道
问题: 如果达不到delay的数量,那view_count 不会被赋值,一直为0,例如一篇很普通的文章,view_count很小,所以该篇文章的view_count一直为0。
建议:将delay的数量改为时间,

例如: :delay=>5,就是代表5分钟同步到数据库。如果为0则不同步。

但是,在实际应用中,因为要更新view_count的业务逻辑会复杂一下,建议使用消息队列完成此类工作。


可能你没有理解到,用于显示的不是 views_count 而是 views_count_s (acts_as_views_count 里面封装的,它的值是 Cache 里面dalay的数字 + 数据库里面存放的数字)
用这个并不会影响最终的显示结果,只是仅仅把写入数据库延迟了


是结果显示没有问题,我说滴问题是, 如果达不到delay的数量,就不会写到数据库。你的数据库,就永远不会有值。你的值是保存在cache中,例如:排序等工作就会出现问题。


确实会有排序的问题
不过我认为这个应用还是看实际的应用情况的,一般只用把延迟是到20左右就好了,而 20 左右的排序差距不是很在意(为了性能),另外基本上很少会用到使用 访问量 来作为排序的(我们的情况,除非是某个栏目文章很热门的,而让有热门度的时候访问量更新就不是问题了),反而大部分是使用回复数

反过来说,如果页面一分钟(或者说一定时间内)都达不到 delay 设置的那么多 views_count ,那么你是否应该把 delay 改小或者去掉呢?

这个不只是为了延迟,而是为了减少高访问量的时候数据库写入的次数

不过延迟时间也是可以增加的方案
6 楼 edisonlz 2010-01-18  
huacnlee 写道
edisonlz 写道
问题: 如果达不到delay的数量,那view_count 不会被赋值,一直为0,例如一篇很普通的文章,view_count很小,所以该篇文章的view_count一直为0。
建议:将delay的数量改为时间,

例如: :delay=>5,就是代表5分钟同步到数据库。如果为0则不同步。

但是,在实际应用中,因为要更新view_count的业务逻辑会复杂一下,建议使用消息队列完成此类工作。


可能你没有理解到,用于显示的不是 views_count 而是 views_count_s (acts_as_views_count 里面封装的,它的值是 Cache 里面dalay的数字 + 数据库里面存放的数字)
用这个并不会影响最终的显示结果,只是仅仅把写入数据库延迟了


是结果显示没有问题,我说滴问题是, 如果达不到delay的数量,就不会写到数据库。你的数据库,就永远不会有值。你的值是保存在cache中,例如:排序等工作就会出现问题。
5 楼 huacnlee 2010-01-18  
edisonlz 写道
问题: 如果达不到delay的数量,那view_count 不会被赋值,一直为0,例如一篇很普通的文章,view_count很小,所以该篇文章的view_count一直为0。
建议:将delay的数量改为时间,

例如: :delay=>5,就是代表5分钟同步到数据库。如果为0则不同步。

但是,在实际应用中,因为要更新view_count的业务逻辑会复杂一下,建议使用消息队列完成此类工作。


可能你没有理解到,用于显示的不是 views_count 而是 views_count_s (acts_as_views_count 里面封装的,它的值是 Cache 里面dalay的数字 + 数据库里面存放的数字)
用这个并不会影响最终的显示结果,只是仅仅把写入数据库延迟了
4 楼 edisonlz 2010-01-15  
问题: 如果达不到delay的数量,那view_count 不会被赋值,一直为0,例如一篇很普通的文章,view_count很小,所以该篇文章的view_count一直为0。
建议:将delay的数量改为时间,

例如: :delay=>5,就是代表5分钟同步到数据库。如果为0则不同步。

但是,在实际应用中,因为要更新view_count的业务逻辑会复杂一下,建议使用消息队列完成此类工作。
3 楼 huacnlee 2010-01-15  
Hooopo 写道
貌似有问题呀,如果页面使用了缓存,action就不会被执行(比如page_cache)。那么这句也就没意义了:
@post.update_views_count


而view里的代码在缓存以后也不能被执行(当然这个可以用片段缓存解决)...


你们都用 cache_page 或 cache_action 来做页面缓存吗?
我这不是,基本上都是局部缓存或Model缓存的
2 楼 Hooopo 2010-01-15  
貌似有问题呀,如果页面使用了缓存,action就不会被执行(比如page_cache)。那么这句也就没意义了:
@post.update_views_count


而view里的代码在缓存以后也不能被执行(当然这个可以用片段缓存解决)...
1 楼 ywencn 2010-01-15  
额,似乎不错。挺实用的。

相关推荐

Global site tag (gtag.js) - Google Analytics