PERF: Use UserAction to count accepted answers (#162)

PERF: Use UserAction to count accepted answers (#162)

The previous query which used custom fields performed a much more complex and slower search.

diff --git a/plugin.rb b/plugin.rb
index 9f6c902..dd9fa14 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -687,12 +687,13 @@ SQL
     }
   end
 
-  add_to_serializer(:user_card, :accepted_answers) do
-    Post
-      .where(user_id: object.id)
-      .joins(:_custom_fields)
-      .where(_custom_fields: { name: 'is_accepted_answer', value: 'true' })
-      .count
+  if defined?(UserAction::SOLVED)
+    add_to_serializer(:user_card, :accepted_answers) do
+      UserAction
+        .where(user_id: object.id)
+        .where(action_type: UserAction::SOLVED)
+        .count
+    end
   end
 
   if respond_to?(:register_topic_list_preload_user_ids)
diff --git a/spec/serializers/user_card_serializer_spec.rb b/spec/serializers/user_card_serializer_spec.rb
index 56eafcd..fe655d1 100644
--- a/spec/serializers/user_card_serializer_spec.rb
+++ b/spec/serializers/user_card_serializer_spec.rb
@@ -8,12 +8,15 @@ describe UserCardSerializer do
   let(:json) { serializer.as_json }
 
   it "accepted_answers serializes number of accepted answers" do
-    post = Fabricate(:post, user: user)
-    post.upsert_custom_fields(is_accepted_answer: 'true')
+    post1 = Fabricate(:post, user: user)
+    DiscourseSolved.accept_answer!(post1, Discourse.system_user)
     expect(serializer.as_json[:accepted_answers]).to eq(1)
 
-    post = Fabricate(:post, user: user)
-    post.upsert_custom_fields(is_accepted_answer: 'true')
+    post2 = Fabricate(:post, user: user)
+    DiscourseSolved.accept_answer!(post2, Discourse.system_user)
     expect(serializer.as_json[:accepted_answers]).to eq(2)
+
+    DiscourseSolved.unaccept_answer!(post1)
+    expect(serializer.as_json[:accepted_answers]).to eq(1)
   end
 end

GitHub sha: b558caff376c1d24f34f9b27c5f91f281e6b1332

This commit appears in #162 which was approved by eviltrout. It was merged by nbianca.