Add excerpt column to topics table to remove N+1 query in ListableTopicSerializer

This commit is contained in:
Neil Lalonde 2014-03-18 13:40:40 -04:00
parent 3cf0adaed0
commit 0b1550f9d4
6 changed files with 50 additions and 5 deletions

View File

@ -64,11 +64,6 @@ class ListableTopicSerializer < BasicTopicSerializer
pinned
end
def excerpt
# excerpt should be hoisted into topic, this is an N+1 query ... yuck
object.posts.by_post_number.first.try(:excerpt, 220, strip_links: true) || nil
end
def pinned
PinnedCheck.new(object, object.user_data).pinned?
end

View File

@ -0,0 +1,18 @@
class AddExcerptToTopics < ActiveRecord::Migration
def up
add_column :topics, :excerpt, :string, limit: 1000
topic_ids = execute("SELECT id FROM topics WHERE pinned_at IS NOT NULL").map {|r| r['id'].to_i }
topic_ids.each do |topic_id|
cooked = execute("SELECT cooked FROM posts WHERE topic_id = #{topic_id} ORDER BY post_number ASC LIMIT 1")[0]['cooked']
if cooked
excerpt = ExcerptParser.get_excerpt(cooked, 220, strip_links: true)
execute "UPDATE topics SET excerpt = #{ActiveRecord::Base.sanitize(excerpt)} WHERE id = #{topic_id}"
end
end
end
def down
remove_column :topics, :excerpt
end
end

View File

@ -188,6 +188,7 @@ class PostCreator
attrs = {last_posted_at: @post.created_at, last_post_user_id: @post.user_id}
attrs[:bumped_at] = @post.created_at unless @post.no_bump
attrs[:word_count] = (@topic.word_count || 0) + @post.word_count
attrs[:excerpt] = @post.excerpt(220, strip_links: true) if new_topic?
@topic.update_attributes(attrs)
end

View File

@ -14,6 +14,7 @@ class PostRevisor
@post.acting_user = @user
revise_post
update_category_description
update_topic_excerpt
post_process_post
update_topic_word_counts
@post.advance_draft_sequence
@ -107,6 +108,10 @@ class PostRevisor
end
end
def update_topic_excerpt
@post.topic.update_column(:excerpt, @post.excerpt(220, strip_links: true)) if @post.post_number == 1
end
def post_process_post
@post.invalidate_oneboxes = true
@post.trigger_post_process

View File

@ -184,6 +184,16 @@ describe PostCreator do
user2.user_stat.reload.topic_reply_count.should == 1
end
it 'sets topic excerpt if first post, but not second post' do
first_post = creator.create
topic = first_post.topic.reload
topic.excerpt.should be_present
expect {
PostCreator.new(first_post.user, topic_id: first_post.topic_id, raw: "this is the second post").create
topic.reload
}.to_not change { topic.excerpt }
end
end
context 'when auto-close param is given' do

View File

@ -271,5 +271,21 @@ describe PostRevisor do
end
end
end
describe "topic excerpt" do
it "topic excerpt is updated only if first post is revised" do
revisor = described_class.new(post)
first_post = topic.posts.by_post_number.first
expect {
revisor.revise!(first_post.user, 'Edit the first post', revised_at: first_post.updated_at + 10.seconds)
topic.reload
}.to change { topic.excerpt }
second_post = Fabricate(:post, post_args.merge(post_number: 2, topic_id: topic.id))
expect {
described_class.new(second_post).revise!(second_post.user, 'Edit the 2nd post')
topic.reload
}.to_not change { topic.excerpt }
end
end
end
end