diff --git a/app/serializers/listable_topic_serializer.rb b/app/serializers/listable_topic_serializer.rb index 56e1ac8c373..b82e2a124ad 100644 --- a/app/serializers/listable_topic_serializer.rb +++ b/app/serializers/listable_topic_serializer.rb @@ -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 diff --git a/db/migrate/20140318150412_add_excerpt_to_topics.rb b/db/migrate/20140318150412_add_excerpt_to_topics.rb new file mode 100644 index 00000000000..35283cb47b5 --- /dev/null +++ b/db/migrate/20140318150412_add_excerpt_to_topics.rb @@ -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 diff --git a/lib/post_creator.rb b/lib/post_creator.rb index 92973568a69..29bfd6281bf 100644 --- a/lib/post_creator.rb +++ b/lib/post_creator.rb @@ -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 diff --git a/lib/post_revisor.rb b/lib/post_revisor.rb index b42927a6d21..39882563fc2 100644 --- a/lib/post_revisor.rb +++ b/lib/post_revisor.rb @@ -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 diff --git a/spec/components/post_creator_spec.rb b/spec/components/post_creator_spec.rb index 5787525cd41..e2323cccc4c 100644 --- a/spec/components/post_creator_spec.rb +++ b/spec/components/post_creator_spec.rb @@ -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 diff --git a/spec/components/post_revisor_spec.rb b/spec/components/post_revisor_spec.rb index d83d84a3f33..76dc8ce0e05 100644 --- a/spec/components/post_revisor_spec.rb +++ b/spec/components/post_revisor_spec.rb @@ -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