added best=N option to get N best comment on a post

This commit is contained in:
Sam 2013-03-27 22:53:11 -07:00
parent e263cb81ca
commit 2295290383
4 changed files with 32 additions and 13 deletions

View File

@ -71,7 +71,7 @@ class PostsController < ApplicationController
post_serializer.draft_sequence = DraftSequence.current(current_user, post.topic.draft_key)
link_counts = TopicLinkClick.counts_for(post.topic, [post])
post_serializer.single_post_link_counts = link_counts[post.id] if link_counts.present?
post_serializer.topic_slug = post.topic.slug if post.topic.present?
result = {post: post_serializer.as_json}
if revisor.category_changed.present?

View File

@ -168,7 +168,7 @@ class TopicsController < ApplicationController
private
def create_topic_view
opts = params.slice(:username_filters, :best_of, :page, :post_number, :posts_before, :posts_after)
opts = params.slice(:username_filters, :best_of, :page, :post_number, :posts_before, :posts_after, :best)
@topic_view = TopicView.new(params[:id] || params[:topic_id], current_user, opts)
end

View File

@ -20,6 +20,8 @@ class TopicView
Guardian.new(user).ensure_can_see!(@topic)
@post_number, @page = options[:post_number], options[:page]
@limit = options[:limit] || SiteSetting.posts_per_page;
@filtered_posts = @topic.posts
@filtered_posts = @filtered_posts.with_deleted if user.try(:admin?)
@filtered_posts = @filtered_posts.best_of if options[:best_of].present?
@ -91,13 +93,16 @@ class TopicView
return filter_posts_near(opts[:post_number].to_i) if opts[:post_number].present?
return filter_posts_before(opts[:posts_before].to_i) if opts[:posts_before].present?
return filter_posts_after(opts[:posts_after].to_i) if opts[:posts_after].present?
return filter_best(opts[:best]) if opts[:best].present?
filter_posts_paged(opts[:page].to_i)
end
# Find the sort order for a post in the topic
def sort_order_for_post_number(post_number)
Post.where(topic_id: @topic.id, post_number: post_number)
.with_deleted
.select(:sort_order)
.first
.try(:sort_order)
end
@ -148,14 +153,12 @@ class TopicView
sort_order = sort_order_for_post_number(post_number)
return nil unless sort_order
# Find posts before the `sort_order`
@posts = @filtered_posts.order('sort_order desc').where("sort_order < ?", sort_order)
@index_offset = @posts.count
@index_reverse = true
@posts = @posts.includes(:reply_to_user).includes(:topic).joins(:user).limit(SiteSetting.posts_per_page)
@posts = @posts.includes(:reply_to_user).includes(:topic).joins(:user).limit(@limit)
end
# Filter to all posts after a particular post number
@ -167,7 +170,16 @@ class TopicView
@index_offset = @filtered_posts.where("sort_order <= ?", sort_order).count
@posts = @filtered_posts.order('sort_order').where("sort_order > ?", sort_order)
@posts = @posts.includes(:reply_to_user).includes(:topic).joins(:user).limit(SiteSetting.posts_per_page)
@posts = @posts.includes(:reply_to_user).includes(:topic).joins(:user).limit(@limit)
end
def filter_best(max)
@index_offset = 0
@posts = @filtered_posts.order('percent_rank asc, sort_order asc').where("post_number > 1")
@posts = @posts.includes(:reply_to_user).includes(:topic).joins(:user).limit(max)
@posts = @posts.to_a
@posts.sort!{|a,b| a.post_number <=> b.post_number}
@posts
end
def read?(post_number)

View File

@ -19,15 +19,22 @@ describe TopicView do
end
context "with a few sample posts" do
let!(:p1) { Fabricate(:post, topic: topic, user: first_poster )}
let!(:p2) { Fabricate(:post, topic: topic, user: coding_horror )}
let!(:p3) { Fabricate(:post, topic: topic, user: first_poster )}
let!(:p1) { Fabricate(:post, topic: topic, user: first_poster, percent_rank: 1 )}
let!(:p2) { Fabricate(:post, topic: topic, user: coding_horror, percent_rank: 0.5 )}
let!(:p3) { Fabricate(:post, topic: topic, user: first_poster, percent_rank: 0 )}
it "it can the best 2 responses" do
best2 = TopicView.new(topic.id, nil, best: 2)
best2.posts.count.should == 2
best2.posts[0].id.should == p2.id
best2.posts[1].id.should == p3.id
end
it "raises NotLoggedIn if the user isn't logged in and is trying to view a private message" do
Topic.any_instance.expects(:private_message?).returns(true)
lambda { TopicView.new(topic.id, nil) }.should raise_error(Discourse::NotLoggedIn)
end
it "raises NotLoggedIn if the user isn't logged in and is trying to view a private message" do
Topic.any_instance.expects(:private_message?).returns(true)
lambda { TopicView.new(topic.id, nil) }.should raise_error(Discourse::NotLoggedIn)
end
it "provides an absolute url" do
topic_view.absolute_url.should be_present