我在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。有解决方案吗谢谢!
答案 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