Commit deeae934710549c89481c76ca33d18bf362b18fb
1 parent
463d8150
Exists in
staging
and in
26 other branches
ActionItem51: listing most recent and more commented
articles and most recent comments git-svn-id: https://svn.colivre.coop.br/svn/noosfero/trunk@1587 3f533792-8f58-4932-b0fe-aaf55b0a4547
Showing
7 changed files
with
110 additions
and
1 deletions
Show diff stats
app/models/article.rb
| @@ -33,6 +33,12 @@ class Article < ActiveRecord::Base | @@ -33,6 +33,12 @@ class Article < ActiveRecord::Base | ||
| 33 | self.find(:all, options) | 33 | self.find(:all, options) |
| 34 | end | 34 | end |
| 35 | 35 | ||
| 36 | + # retrives the most commented articles, sorted by the comment count (largest | ||
| 37 | + # first) | ||
| 38 | + def self.most_commented(limit) | ||
| 39 | + find(:all, :order => 'comments_count DESC', :limit => limit) | ||
| 40 | + end | ||
| 41 | + | ||
| 36 | # produces the HTML code that is to be displayed as this article's contents. | 42 | # produces the HTML code that is to be displayed as this article's contents. |
| 37 | # | 43 | # |
| 38 | # The implementation in this class just provides the +body+ attribute as the | 44 | # The implementation in this class just provides the +body+ attribute as the |
app/models/category.rb
| @@ -21,4 +21,17 @@ class Category < ActiveRecord::Base | @@ -21,4 +21,17 @@ class Category < ActiveRecord::Base | ||
| 21 | 21 | ||
| 22 | acts_as_filesystem | 22 | acts_as_filesystem |
| 23 | 23 | ||
| 24 | + has_and_belongs_to_many :articles | ||
| 25 | + def recent_articles(limit = 10) | ||
| 26 | + self.articles.recent(limit) | ||
| 27 | + end | ||
| 28 | + | ||
| 29 | + def recent_comments(limit = 10) | ||
| 30 | + # FIXME this can become SLOW | ||
| 31 | + Comment.find(:all, :order => 'created_on DESC, comments.id DESC', :limit => limit, :conditions => { :article_id => article_ids}) | ||
| 32 | + end | ||
| 33 | + | ||
| 34 | + def most_commented_articles(limit = 10) | ||
| 35 | + self.articles.most_commented(limit) | ||
| 36 | + end | ||
| 24 | end | 37 | end |
app/models/comment.rb
| 1 | class Comment < ActiveRecord::Base | 1 | class Comment < ActiveRecord::Base |
| 2 | validates_presence_of :title, :body | 2 | validates_presence_of :title, :body |
| 3 | - belongs_to :article | 3 | + belongs_to :article, :counter_cache => true |
| 4 | belongs_to :author, :class_name => 'Person', :foreign_key => 'author_id' | 4 | belongs_to :author, :class_name => 'Person', :foreign_key => 'author_id' |
| 5 | 5 | ||
| 6 | # unauthenticated authors: | 6 | # unauthenticated authors: |
| @@ -0,0 +1,13 @@ | @@ -0,0 +1,13 @@ | ||
| 1 | +class AddsCommentCountToArticle < ActiveRecord::Migration | ||
| 2 | + def self.up | ||
| 3 | + add_column :articles, :comments_count, :integer, :default => 0 | ||
| 4 | + add_column :article_versions, :comments_count, :integer | ||
| 5 | + | ||
| 6 | + execute "update articles set comments_count = (select count(*) from comments where comments.article_id = articles.id)" | ||
| 7 | + end | ||
| 8 | + | ||
| 9 | + def self.down | ||
| 10 | + remove_column :article_versions, :comments_count | ||
| 11 | + remove_column :articles, :comments_count | ||
| 12 | + end | ||
| 13 | +end |
test/unit/article_test.rb
| @@ -204,4 +204,17 @@ class ArticleTest < Test::Unit::TestCase | @@ -204,4 +204,17 @@ class ArticleTest < Test::Unit::TestCase | ||
| 204 | end | 204 | end |
| 205 | end | 205 | end |
| 206 | 206 | ||
| 207 | + should 'list most commented articles' do | ||
| 208 | + Article.delete_all | ||
| 209 | + | ||
| 210 | + person = create_user('testuser').person | ||
| 211 | + articles = (1..4).map {|n| a = person.articles.build(:name => "art #{n}"); a.save!; a } | ||
| 212 | + | ||
| 213 | + 2.times { articles[0].comments.build(:title => 'test', :body => 'asdsad', :author => person).save! } | ||
| 214 | + 4.times { articles[1].comments.build(:title => 'test', :body => 'asdsad', :author => person).save! } | ||
| 215 | + | ||
| 216 | + # should respect the order (more commented comes first) | ||
| 217 | + assert_equal [articles[1], articles[0]], person.articles.most_commented(2) | ||
| 218 | + end | ||
| 219 | + | ||
| 207 | end | 220 | end |
test/unit/category_test.rb
| @@ -210,4 +210,58 @@ class CategoryTest < Test::Unit::TestCase | @@ -210,4 +210,58 @@ class CategoryTest < Test::Unit::TestCase | ||
| 210 | assert_equal [ 'parent', 'child'], c2.explode_path | 210 | assert_equal [ 'parent', 'child'], c2.explode_path |
| 211 | end | 211 | end |
| 212 | 212 | ||
| 213 | + ################################################################ | ||
| 214 | + # category filter stuff | ||
| 215 | + ################################################################ | ||
| 216 | + | ||
| 217 | + should 'list recent articles' do | ||
| 218 | + c = @env.categories.build(:name => 'my category'); c.save! | ||
| 219 | + person = create_user('testuser').person | ||
| 220 | + | ||
| 221 | + a1 = person.articles.build(:name => 'art1') | ||
| 222 | + a1.categories << c | ||
| 223 | + a1.save! | ||
| 224 | + | ||
| 225 | + a2 = person.articles.build(:name => 'art2') | ||
| 226 | + a2.categories << c | ||
| 227 | + a2.save! | ||
| 228 | + | ||
| 229 | + assert_equivalent [a1, a2], c.recent_articles | ||
| 230 | + end | ||
| 231 | + | ||
| 232 | + | ||
| 233 | + should 'list recent comments' do | ||
| 234 | + c = @env.categories.build(:name => 'my category'); c.save! | ||
| 235 | + person = create_user('testuser').person | ||
| 236 | + | ||
| 237 | + a1 = person.articles.build(:name => 'art1') | ||
| 238 | + a1.categories << c | ||
| 239 | + a1.save! | ||
| 240 | + c1 = a1.comments.build(:title => 'comm1', :body => 'khdkashd ', :author => person); c1.save! | ||
| 241 | + | ||
| 242 | + a2 = person.articles.build(:name => 'art2') | ||
| 243 | + a2.categories << c | ||
| 244 | + a2.save! | ||
| 245 | + c2 = a2.comments.build(:title => 'comm1', :body => 'khdkashd ', :author => person); c2.save! | ||
| 246 | + | ||
| 247 | + assert_equivalent [c1, c2], c.recent_comments | ||
| 248 | + end | ||
| 249 | + | ||
| 250 | + should 'list most commented articles' do | ||
| 251 | + c = @env.categories.build(:name => 'my category'); c.save! | ||
| 252 | + person = create_user('testuser').person | ||
| 253 | + | ||
| 254 | + a1 = person.articles.build(:name => 'art1', :categories => [c]); a1.save! | ||
| 255 | + a2 = person.articles.build(:name => 'art2', :categories => [c]); a2.save! | ||
| 256 | + a3 = person.articles.build(:name => 'art3', :categories => [c]); a3.save! | ||
| 257 | + | ||
| 258 | + a1.comments.build(:title => 'test', :body => 'asdsa', :author => person).save! | ||
| 259 | + 5.times { a2.comments.build(:title => 'test', :body => 'asdsa', :author => person).save! } | ||
| 260 | + | ||
| 261 | + 10.times { a3.comments.build(:title => 'test', :body => 'kajsdsa', :author => person).save! } | ||
| 262 | + | ||
| 263 | + assert_equal [a3, a2], c.most_commented_articles(2) | ||
| 264 | + | ||
| 265 | + end | ||
| 266 | + | ||
| 213 | end | 267 | end |
test/unit/comment_test.rb
| @@ -59,4 +59,14 @@ class CommentTest < Test::Unit::TestCase | @@ -59,4 +59,14 @@ class CommentTest < Test::Unit::TestCase | ||
| 59 | assert c1.errors.invalid?(:name) | 59 | assert c1.errors.invalid?(:name) |
| 60 | end | 60 | end |
| 61 | 61 | ||
| 62 | + should 'update counter cache in article' do | ||
| 63 | + owner = create_user('testuser').person | ||
| 64 | + art = owner.articles.build(:name => 'ytest'); art.save! | ||
| 65 | + | ||
| 66 | + cc = art.comments_count | ||
| 67 | + art.comments.build(:title => 'test comment', :body => 'anything', :author => owner).save! | ||
| 68 | + art.reload | ||
| 69 | + assert_equal cc + 1, art.comments_count | ||
| 70 | + end | ||
| 71 | + | ||
| 62 | end | 72 | end |