From deeae934710549c89481c76ca33d18bf362b18fb Mon Sep 17 00:00:00 2001 From: AntonioTerceiro Date: Tue, 18 Mar 2008 18:15:31 +0000 Subject: [PATCH] ActionItem51: listing most recent and more commented articles and most recent comments --- app/models/article.rb | 6 ++++++ app/models/category.rb | 13 +++++++++++++ app/models/comment.rb | 2 +- db/migrate/026_adds_comment_count_to_article.rb | 13 +++++++++++++ test/unit/article_test.rb | 13 +++++++++++++ test/unit/category_test.rb | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/unit/comment_test.rb | 10 ++++++++++ 7 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 db/migrate/026_adds_comment_count_to_article.rb diff --git a/app/models/article.rb b/app/models/article.rb index e08c41f..7fd03e2 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -33,6 +33,12 @@ class Article < ActiveRecord::Base self.find(:all, options) end + # retrives the most commented articles, sorted by the comment count (largest + # first) + def self.most_commented(limit) + find(:all, :order => 'comments_count DESC', :limit => limit) + end + # produces the HTML code that is to be displayed as this article's contents. # # The implementation in this class just provides the +body+ attribute as the diff --git a/app/models/category.rb b/app/models/category.rb index fff903c..ced7c88 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -21,4 +21,17 @@ class Category < ActiveRecord::Base acts_as_filesystem + has_and_belongs_to_many :articles + def recent_articles(limit = 10) + self.articles.recent(limit) + end + + def recent_comments(limit = 10) + # FIXME this can become SLOW + Comment.find(:all, :order => 'created_on DESC, comments.id DESC', :limit => limit, :conditions => { :article_id => article_ids}) + end + + def most_commented_articles(limit = 10) + self.articles.most_commented(limit) + end end diff --git a/app/models/comment.rb b/app/models/comment.rb index 2bccb89..e99f35d 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -1,6 +1,6 @@ class Comment < ActiveRecord::Base validates_presence_of :title, :body - belongs_to :article + belongs_to :article, :counter_cache => true belongs_to :author, :class_name => 'Person', :foreign_key => 'author_id' # unauthenticated authors: diff --git a/db/migrate/026_adds_comment_count_to_article.rb b/db/migrate/026_adds_comment_count_to_article.rb new file mode 100644 index 0000000..ae10910 --- /dev/null +++ b/db/migrate/026_adds_comment_count_to_article.rb @@ -0,0 +1,13 @@ +class AddsCommentCountToArticle < ActiveRecord::Migration + def self.up + add_column :articles, :comments_count, :integer, :default => 0 + add_column :article_versions, :comments_count, :integer + + execute "update articles set comments_count = (select count(*) from comments where comments.article_id = articles.id)" + end + + def self.down + remove_column :article_versions, :comments_count + remove_column :articles, :comments_count + end +end diff --git a/test/unit/article_test.rb b/test/unit/article_test.rb index ad88a8b..6d0d408 100644 --- a/test/unit/article_test.rb +++ b/test/unit/article_test.rb @@ -204,4 +204,17 @@ class ArticleTest < Test::Unit::TestCase end end + should 'list most commented articles' do + Article.delete_all + + person = create_user('testuser').person + articles = (1..4).map {|n| a = person.articles.build(:name => "art #{n}"); a.save!; a } + + 2.times { articles[0].comments.build(:title => 'test', :body => 'asdsad', :author => person).save! } + 4.times { articles[1].comments.build(:title => 'test', :body => 'asdsad', :author => person).save! } + + # should respect the order (more commented comes first) + assert_equal [articles[1], articles[0]], person.articles.most_commented(2) + end + end diff --git a/test/unit/category_test.rb b/test/unit/category_test.rb index 840d5e4..8b57c27 100644 --- a/test/unit/category_test.rb +++ b/test/unit/category_test.rb @@ -210,4 +210,58 @@ class CategoryTest < Test::Unit::TestCase assert_equal [ 'parent', 'child'], c2.explode_path end + ################################################################ + # category filter stuff + ################################################################ + + should 'list recent articles' do + c = @env.categories.build(:name => 'my category'); c.save! + person = create_user('testuser').person + + a1 = person.articles.build(:name => 'art1') + a1.categories << c + a1.save! + + a2 = person.articles.build(:name => 'art2') + a2.categories << c + a2.save! + + assert_equivalent [a1, a2], c.recent_articles + end + + + should 'list recent comments' do + c = @env.categories.build(:name => 'my category'); c.save! + person = create_user('testuser').person + + a1 = person.articles.build(:name => 'art1') + a1.categories << c + a1.save! + c1 = a1.comments.build(:title => 'comm1', :body => 'khdkashd ', :author => person); c1.save! + + a2 = person.articles.build(:name => 'art2') + a2.categories << c + a2.save! + c2 = a2.comments.build(:title => 'comm1', :body => 'khdkashd ', :author => person); c2.save! + + assert_equivalent [c1, c2], c.recent_comments + end + + should 'list most commented articles' do + c = @env.categories.build(:name => 'my category'); c.save! + person = create_user('testuser').person + + a1 = person.articles.build(:name => 'art1', :categories => [c]); a1.save! + a2 = person.articles.build(:name => 'art2', :categories => [c]); a2.save! + a3 = person.articles.build(:name => 'art3', :categories => [c]); a3.save! + + a1.comments.build(:title => 'test', :body => 'asdsa', :author => person).save! + 5.times { a2.comments.build(:title => 'test', :body => 'asdsa', :author => person).save! } + + 10.times { a3.comments.build(:title => 'test', :body => 'kajsdsa', :author => person).save! } + + assert_equal [a3, a2], c.most_commented_articles(2) + + end + end diff --git a/test/unit/comment_test.rb b/test/unit/comment_test.rb index 2ffa5ae..40618d3 100644 --- a/test/unit/comment_test.rb +++ b/test/unit/comment_test.rb @@ -59,4 +59,14 @@ class CommentTest < Test::Unit::TestCase assert c1.errors.invalid?(:name) end + should 'update counter cache in article' do + owner = create_user('testuser').person + art = owner.articles.build(:name => 'ytest'); art.save! + + cc = art.comments_count + art.comments.build(:title => 'test comment', :body => 'anything', :author => owner).save! + art.reload + assert_equal cc + 1, art.comments_count + end + end -- libgit2 0.21.2