我有一个包含约1000个俱乐部和10,000个用户的数据库。我需要构建一个表,以连续显示每个俱乐部,并在该列中列出与该俱乐部相关联的用户数量,帖子和评论。我现在有这样的查询(从我的控制器):
@clubs.find_each do |club|
@users.where(:club_id => club.club_id).find_each do |user|
@numPostsByClub += user.posts.count
@numCommentsByClub += user.comments.count
现在,我想必须有一种更有效的方法来执行此操作,因为页面加载大约需要90秒。是不是有一种更有效的方式来加载所有这些数据,或者是一种运行rake任务(我每天只需要更新一次数据)来存储所有这些数据以便快速访问的方法?
如果我对您的理解正确,则需要按俱乐部分类的评论总数和按俱乐部分类的评论总数。
如果您想快速回答以下问题, counter_cache将为您提供帮助:
但不包含每个俱乐部的帖子或评论总数(尽管这会使您的生活更轻松)。
免责声明:在未创建数据库备份且未阅读完整答案的情况下,请勿在生产中开始实施以下建议。
要使脚本更快,请在clubs表中添加2列:
class AddCommentsCountToClubs < ActiveRecord::Migration
def change
add_column :clubs, :comments_count, :integer, default: 0
end
end
class AddPostsCountToClubs < ActiveRecord::Migration
def change
add_column :clubs, :posts_count, :integer, default: 0
end
end
对于每个俱乐部:
要创建将更新计数器的瑞克任务,请添加lib/tasks/update_clubs_counters.rake
具有以下内容的文件:
namespace :db do
task :update_clubs_counters => :environment do
Club.all.each do |club|
club.update(comments_count: club.comments.count, posts_count: club.posts.count)
end
end
end
创建文件后,运行 bundle exec rake db:update_clubs_counters
更新计数器的另一种方法是使用rails控制台并运行任务的内容(仅与更新有关的部分)
然后,对于Comment和Post模型,添加2个回调以增加/减少来自每个相应俱乐部的计数器。
为了清楚起见,我将定义所有涉及的模型及其之间的关系
class Club < ActiveRecord::Base
has_many :users
has_many :comments, through: :users
has_many :posts, through: :users
end
class User < ActiveRecord::Base
belongs_to :club
has_many :posts
end
class Comment < ActiveRecord::Base
belongs_to :user
after_create :increment_club_comments_count
after_destroy :decrement_club_comments_count
def increment_club_comments_count
Club.increment_counter( :comments_count, user.club_id )
end
def decrement_club_comments_count
Club.decrement_counter( :comments_count, user.club_id )
end
end
class Post < ActiveRecord::Base
belongs_to :user
after_create :increment_club_posts_count
after_destroy :decrement_club_posts_count
def increment_club_posts_count
Club.increment_counter( :posts_count, user.club_id )
end
def decrement_club_posts_count
Club.decrement_counter( :posts_count, user.club_id )
end
end
现在,每次添加/删除帖子/评论时,clubs表中的相应计数器都会增加/减少。
您可以像这样简化控制器(只需一个查询,您就可以拥有所有数据):
@clubs = Club.all # I recommend to use pagination and not to list all 1000 clubs at once
在您的视图中,您只需显示您的计数器,如下所示:
<% @clubs.each do |club| %>
<p>Comments Count: <%= club.comments_count %></p>
<p>Posts Count: <%= club.posts_count %></p>
<% end %>
你可以找到更多的细节increment_counter和decrement_counter和counter_cache用的has_many:通过
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句