Rails计算属于用户的所有帖子的页面视图

时间:2015-03-02 13:04:52

标签: ruby-on-rails ruby

我在rails网站上有一个ruby,它有一个用户模型和一个帖子模型

# models/user.rb
class User < ActiveRecord::Base
  has_many :posts
end

# models/post.rb
class Post < ActiveRecord::Base
  belongs_to :user
  is_impressionable
end

如您所见,我已使用impressionist gem计算每个帖子的网页浏览量。 要获取特定帖子的页面查看次数,我使用post.impressionist_count。

如何有效地获取特定用户的所有帖子的页面浏览量总和?最好将此值存储在数据库中,因为我可能需要它来进行更多操作。此外,如果我将此值存储在数据库中,每次帖子的视图计数更改时如何更新它?提前谢谢!

更新

谢谢大家的回答。我试图整合你的解决方案,但我仍然找不到。

我使用了counter_cache

add_column :posts, :view_count, :integer, default: 0

# models/post.rb
is_impressionable :counter_cache => true, :column_name => :view_count

在用户表中添加了一列

add_column :users, :total_view_count, :integer, default: 0

然后做了这个

# posts_controller
before_action :update_user_total_view_count, only: :show

private
    def update_user_total_view_count
        @post = Post.find(params[:id]);
        @post.user.update_user_total_view_count
    end

# user model
def update_user_total_view_count
    update(total_view_count: posts.sum(:view_count))
end

我不能使用posts.sum(:impressionist_count),因为它不是数据库中的列。我以为我有这个工作,但是post模型上的view_count没有正确更新,即使impressionist_count增加也停留在1。有解决方案吗谢谢!

3 个答案:

答案 0 :(得分:0)

您可能需要使用counter_cache的ActiveRecord内置机制,您正在定义将存储缓存值的新列。有非常快速的描述如何继续:

https://coderwall.com/p/tlvgag/easily-keep-track-of-rails-relationship-count-with-counter_cache

上面描述的是自己实现解决方案,但gem有自己的方式来存储缓存的计数器。你尝试过这里描述的内容吗?

https://github.com/charlotte-ruby/impressionist#adding-a-counter-cache

答案 1 :(得分:0)

我认为你可以做这样的事情:

total_impressions = Rails.cache.fetch("user:#{particular_user.id}:total_impressions") do
  Post.where(user: particular_user).reduce(0) do |sum, post|
    sum + post.impressionist_count(:filter=>:all)
  end
end

正如您所见,此代码可计算总展示次数并对其进行缓存。

我不太了解impressionist gem,但可能有可能改进此代码并计算数据库端的总展示次数。

答案 2 :(得分:0)

我想我会在用户模型上创建一个属性:

rails g migration add_total_post_views_to_users total_post_views:integer

然后对show action(Controller)进行前一个操作:

class PostsController < ApplicationController
  before_action :update_total_post_views, only: :show

  def show 
    # code for displaying the post
  end

  private

  def update_total_post_views
    Post.find(params[:id]).user.update_total_post_views
  end

用户模型:

class User
  has_many :posts

  # more code...

  def update_total_post_views
     update(total_post_views: posts.sum(:impressionist_count)
  end