naive implementation of post_count on categories

This commit is contained in:
Sam 2013-10-17 13:23:38 +11:00
parent 9ad01a1afb
commit 7bf96ee690
4 changed files with 39 additions and 6 deletions

View file

@ -102,18 +102,35 @@ class Category < ActiveRecord::Base
# all categories. # all categories.
def self.update_stats def self.update_stats
topics = Topic topics = Topic
.select("COUNT(*)") .select("COUNT(*) topic_count")
.where("topics.category_id = categories.id") .where("topics.category_id = categories.id")
.where("categories.topic_id <> topics.id") .where("categories.topic_id <> topics.id")
.visible .visible
topic_count = topics.to_sql topics_with_post_count = Topic
.select("topics.category_id, topics.id topic_id, COUNT(*) topic_count, SUM(topics.posts_count) post_count")
.group("topics.category_id, topics.id")
.visible.to_sql
topics_year = topics.created_since(1.year.ago).to_sql topics_year = topics.created_since(1.year.ago).to_sql
topics_month = topics.created_since(1.month.ago).to_sql topics_month = topics.created_since(1.month.ago).to_sql
topics_week = topics.created_since(1.week.ago).to_sql topics_week = topics.created_since(1.week.ago).to_sql
Category.update_all("topic_count = (#{topic_count}),
topics_year = (#{topics_year}), Category.exec_sql <<SQL
UPDATE categories c
SET topic_count = x.topic_count,
post_count = x.post_count
FROM (#{topics_with_post_count}) x
WHERE x.category_id = c.id AND
(c.topic_count <> x.topic_count OR c.post_count <> x.post_count) AND
x.topic_id <> c.topic_id
SQL
# TODO don't update unchanged data
Category.update_all("topics_year = (#{topics_year}),
topics_month = (#{topics_month}), topics_month = (#{topics_month}),
topics_week = (#{topics_week})") topics_week = (#{topics_week})")
end end

View file

@ -0,0 +1,14 @@
class AddPostCountToCategories < ActiveRecord::Migration
def up
add_column :categories, :post_count, :integer, null: false, default: 0
execute <<SQL
UPDATE categories
SET post_count = (SELECT SUM(posts_count) FROM topics
WHERE category_id = categories.id AND deleted_at IS NULL)
SQL
end
def down
remove_column :categories, :post_count
end
end

View file

@ -77,7 +77,7 @@ class SqlBuilder
16 => :value_to_boolean 16 => :value_to_boolean
} }
def map_exec(klass, args = {}) def map_exec(klass = OpenStruct, args = {})
results = exec(args) results = exec(args)
setters = results.fields.each_with_index.map do |f, index| setters = results.fields.each_with_index.map do |f, index|

View file

@ -255,7 +255,7 @@ describe Category do
context 'with regular topics' do context 'with regular topics' do
before do before do
@category.topics << Fabricate(:topic, user: @category.user) create_post(user: @category.user, category: @category.name)
Category.update_stats Category.update_stats
@category.reload @category.reload
end end
@ -265,6 +265,7 @@ describe Category do
@category.topics_month.should == 1 @category.topics_month.should == 1
@category.topics_year.should == 1 @category.topics_year.should == 1
@category.topic_count.should == 1 @category.topic_count.should == 1
@category.post_count.should == 1
end end
end end
@ -282,6 +283,7 @@ describe Category do
@category.topic_count.should == 0 @category.topic_count.should == 0
@category.topics_month.should == 0 @category.topics_month.should == 0
@category.topics_year.should == 0 @category.topics_year.should == 0
@category.post_count.should == 0
end end
end end