diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 0173cdded..a8e7cb3f9 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -123,6 +123,7 @@ class PostsController < ApplicationController revisor = PostRevisor.new(post) if revisor.revise!(current_user, params[:post][:raw], edit_reason: params[:post][:edit_reason]) TopicLink.extract_from(post) + QuotedPost.extract_from(post) end if post.errors.present? diff --git a/app/models/badge.rb b/app/models/badge.rb index 2356f192a..1de4923d6 100644 --- a/app/models/badge.rb +++ b/app/models/badge.rb @@ -45,17 +45,16 @@ SQL SQL FirstQuote = < 0 + ids << results[0]["quoted_post_id"].to_i + end + end + + if ids.length > 0 + exec_sql "DELETE FROM quoted_posts WHERE post_id = :post_id AND quoted_post_id NOT IN (:ids)", + post_id: post.id, ids: ids + end + + end +end diff --git a/app/models/topic.rb b/app/models/topic.rb index 1794402bc..87816f92b 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -487,6 +487,7 @@ class Topic < ActiveRecord::Base # Grab any links that are present TopicLink.extract_from(new_post) + QuotedPost.extract_from(new_post) end new_post diff --git a/db/migrate/20140715055242_add_quoted_posts.rb b/db/migrate/20140715055242_add_quoted_posts.rb new file mode 100644 index 000000000..587d89479 --- /dev/null +++ b/db/migrate/20140715055242_add_quoted_posts.rb @@ -0,0 +1,54 @@ +class AddQuotedPosts < ActiveRecord::Migration + def change + create_table :quoted_posts do |t| + t.integer :post_id, null: false + t.integer :quoted_post_id, null: false + t.timestamps + end + + add_index :quoted_posts, [:post_id, :quoted_post_id], unique: true + add_index :quoted_posts, [:quoted_post_id, :post_id], unique: true + + + # NOTE this can be done in pg but too much of a headache + id = 0 + while id = backfill_batch(id, 1000); end + end + + def backfill_batch(start_id, batch_size) + + results = execute < #{start_id} + ORDER BY id + LIMIT #{batch_size} +SQL + + max_id = nil + + results.each do |row| + post_id, max_id = row["id"].to_i + doc = Nokogiri::HTML.fragment(row["cooked"]) + + uniq = {} + + doc.css("aside.quote[data-topic]").each do |a| + topic_id = a['data-topic'].to_i + post_number = a['data-post'].to_i + + next if uniq[[topic_id,post_number]] + uniq[[topic_id,post_number]] = true + + + execute "INSERT INTO quoted_posts(post_id, quoted_post_id, created_at, updated_at) + SELECT #{post_id}, id, created_at, updated_at + FROM posts + WHERE post_number = #{post_number} AND + topic_id = #{topic_id}" + end + end + + max_id + end +end diff --git a/lib/post_creator.rb b/lib/post_creator.rb index e98913bdc..073f7844d 100644 --- a/lib/post_creator.rb +++ b/lib/post_creator.rb @@ -266,6 +266,7 @@ class PostCreator def extract_links TopicLink.extract_from(@post) + QuotedPost.extract_from(@post) end def track_topic diff --git a/spec/models/quoted_post_spec.rb b/spec/models/quoted_post_spec.rb new file mode 100644 index 000000000..8943e0f75 --- /dev/null +++ b/spec/models/quoted_post_spec.rb @@ -0,0 +1,27 @@ +require 'spec_helper' + +describe QuotedPost do + it 'correctly extracts quotes in integration test' do + post1 = create_post + post2 = create_post(topic_id: post1.topic_id, + raw: "[quote=\"#{post1.user.username}, post: 1, topic:#{post1.topic_id}\"]\ntest\n[/quote]\nthis is a test post") + + QuotedPost.find_by(post_id: post2.id, quoted_post_id: post1.id).should_not be_nil + end + + it 'correctly handles deltas' do + post1 = Fabricate(:post) + post2 = Fabricate(:post) + + post2.cooked = <
techAPJ said:

When the user will v

+HTML + + QuotedPost.create!(post_id: post2.id, quoted_post_id: 999) + + QuotedPost.extract_from(post2) + QuotedPost.where(post_id: post2.id).count.should == 1 + QuotedPost.find_by(post_id: post2.id, quoted_post_id: post1.id).should_not be_nil + + end +end