From ee373fa6c0fdfcae809c90b3e51ef8e7c3794fce Mon Sep 17 00:00:00 2001 From: Molly Struve Date: Tue, 28 Apr 2020 09:55:48 -0500 Subject: [PATCH] [deploy] Remove Algolia from Article Model (#7540) --- app/models/article.rb | 95 ------------------- app/services/moderator/delete_user.rb | 3 +- app/services/users/delete_articles.rb | 1 - app/workers/articles/score_calc_worker.rb | 1 - ...e_index_existing_articles_with_approved.rb | 2 +- ...ex_existing_articles_with_approved_spec.rb | 8 -- spec/models/article_spec.rb | 61 ------------ 7 files changed, 2 insertions(+), 169 deletions(-) delete mode 100644 spec/lib/data_update_scripts/re_index_existing_articles_with_approved_spec.rb diff --git a/app/models/article.rb b/app/models/article.rb index 2237b7c4d..488320686 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -1,7 +1,6 @@ class Article < ApplicationRecord include CloudinaryHelper include ActionView::Helpers - include AlgoliaSearch include Storext.model include Reactable include Searchable @@ -174,70 +173,6 @@ class Article < ApplicationRecord scope :eager_load_serialized_data, -> { includes(:user, :organization, :tags) } - algoliasearch per_environment: true, auto_remove: false, enqueue: :trigger_index do - attribute :title - add_index "searchables", id: :index_id, per_environment: true, enqueue: :trigger_index do - attributes :title, :tag_list, :main_image, :id, :reading_time, :score, - :featured, :published, :published_at, :featured_number, - :comments_count, :reactions_count, :positive_reactions_count, - :path, :class_name, :user_name, :user_username, :comments_blob, - :body_text, :tag_keywords_for_search, :search_score, :readable_publish_date, :flare_tag, :approved - attribute :user do - { username: user.username, name: user.name, - profile_image_90: ProfileImage.new(user).get(width: 90), pro: user.pro? } - end - tags do - [tag_list, - "user_#{user_id}", - "username_#{user&.username}", - "lang_#{language || 'en'}", - ("organization_#{organization_id}" if organization)].flatten.compact - end - searchableAttributes ["unordered(title)", - "body_text", - "tag_list", - "tag_keywords_for_search", - "user_name", - "user_username", - "comments_blob"] - attributesForFaceting %i[class_name approved] - customRanking ["desc(search_score)", "desc(hotness_score)"] - end - - add_index "ordered_articles", id: :index_id, per_environment: true, enqueue: :trigger_index do - attributes :title, :path, :class_name, :comments_count, :reading_time, :language, - :tag_list, :positive_reactions_count, :id, :hotness_score, :score, :readable_publish_date, :flare_tag, :user_id, - :organization_id, :cloudinary_video_url, :video_duration_in_minutes, :experience_level_rating, :experience_level_rating_distribution, :approved - attribute :published_at_int do - published_at.to_i - end - attribute :user do - { username: user.username, - name: user.name, - profile_image_90: ProfileImage.new(user).get(width: 90) } - end - attribute :organization do - if organization - { slug: organization.slug, - name: organization.name, - profile_image_90: ProfileImage.new(organization).get(width: 90) } - end - end - tags do - [tag_list, "user_#{user_id}", "username_#{user&.username}", "lang_#{language || 'en'}", - ("organization_#{organization_id}" if organization)].flatten.compact - end - ranking ["desc(hotness_score)"] - attributesForFaceting %i[class_name approved] - add_replica "ordered_articles_by_positive_reactions_count", inherit: true, per_environment: true do - ranking ["desc(positive_reactions_count)"] - end - add_replica "ordered_articles_by_published_at", inherit: true, per_environment: true do - ranking ["desc(published_at_int)"] - end - end - end - store_attributes :boost_states do boosted_additional_articles Boolean, default: false boosted_dev_digest_email Boolean, default: false @@ -277,19 +212,6 @@ class Article < ApplicationRecord end end - def self.trigger_index(record, remove) - # on destroy an article is removed from index in a before_destroy callback #before_destroy_actions - return if remove - - if record.published && record.tag_list.exclude?("hiring") - Search::IndexWorker.perform_async("Article", record.id) - else - Search::RemoveFromIndexWorker.perform_async(Article.algolia_index_name, record.id) - Search::RemoveFromIndexWorker.perform_async("searchables_#{Rails.env}", record.index_id) - Search::RemoveFromIndexWorker.perform_async("ordered_articles_#{Rails.env}", record.index_id) - end - end - def search_id "article_#{id}" end @@ -306,14 +228,8 @@ class Article < ApplicationRecord ActionView::Base.full_sanitizer.sanitize(processed_html)[0..7000] end - def remove_algolia_index - remove_from_index! - delete_related_objects - end - def touch_by_reaction async_score_calc - index! index_to_elasticsearch end @@ -412,11 +328,6 @@ class Article < ApplicationRecord (video_duration_in_seconds.to_i / 60) % 60 end - # keep public because it's used in algolia jobs - def index_id - "articles-#{id}" - end - def update_score new_score = reactions.sum(:points) + Reaction.where(reactable_id: user_id, reactable_type: "User").sum(:points) update_columns(score: new_score, @@ -427,11 +338,6 @@ class Article < ApplicationRecord private - def delete_related_objects - Search::RemoveFromIndexWorker.new.perform("searchables_#{Rails.env}", index_id) - Search::RemoveFromIndexWorker.new.perform("ordered_articles_#{Rails.env}", index_id) - end - def search_score calculated_score = hotness_score.to_i + ((comments_count * 3).to_i + positive_reactions_count.to_i * 300 * user.reputation_modifier * score.to_i) calculated_score.to_i @@ -513,7 +419,6 @@ class Article < ApplicationRecord def before_destroy_actions bust_cache - remove_algolia_index article_ids = user.article_ids.dup if organization organization.touch(:last_article_at) diff --git a/app/services/moderator/delete_user.rb b/app/services/moderator/delete_user.rb index 64b1e46f1..ede40d824 100644 --- a/app/services/moderator/delete_user.rb +++ b/app/services/moderator/delete_user.rb @@ -43,10 +43,9 @@ module Moderator return unless user.articles.any? # preload associations that are going to be used during indexing - user.articles.preload(:taggings, :organization, :tag_taggings, :tags).find_each do |article| + user.articles.preload(:organization, :tag_taggings, :tags).find_each do |article| path = "/#{@ghost.username}/#{article.slug}" article.update_columns(user_id: @ghost.id, path: path) - article.index! article.index_to_elasticsearch_inline end end diff --git a/app/services/users/delete_articles.rb b/app/services/users/delete_articles.rb index 0170f9177..3e4b21869 100644 --- a/app/services/users/delete_articles.rb +++ b/app/services/users/delete_articles.rb @@ -16,7 +16,6 @@ module Users comment.remove_from_elasticsearch comment.delete end - article.remove_algolia_index article.remove_from_elasticsearch article.delete article.purge diff --git a/app/workers/articles/score_calc_worker.rb b/app/workers/articles/score_calc_worker.rb index cb4d6266e..656a6a3b7 100644 --- a/app/workers/articles/score_calc_worker.rb +++ b/app/workers/articles/score_calc_worker.rb @@ -9,7 +9,6 @@ module Articles return unless article article.update_score - article.index! article.index_to_elasticsearch_inline end end diff --git a/lib/data_update_scripts/20200217131245_re_index_existing_articles_with_approved.rb b/lib/data_update_scripts/20200217131245_re_index_existing_articles_with_approved.rb index 3f81c9256..f3159baa3 100644 --- a/lib/data_update_scripts/20200217131245_re_index_existing_articles_with_approved.rb +++ b/lib/data_update_scripts/20200217131245_re_index_existing_articles_with_approved.rb @@ -1,7 +1,7 @@ module DataUpdateScripts class ReIndexExistingArticlesWithApproved def run - Article.published.find_each { |article| Article.trigger_index(article, false) } + # Reindexed all articles with new approved field end end end diff --git a/spec/lib/data_update_scripts/re_index_existing_articles_with_approved_spec.rb b/spec/lib/data_update_scripts/re_index_existing_articles_with_approved_spec.rb deleted file mode 100644 index 87c9c096a..000000000 --- a/spec/lib/data_update_scripts/re_index_existing_articles_with_approved_spec.rb +++ /dev/null @@ -1,8 +0,0 @@ -require "rails_helper" -require Rails.root.join("lib/data_update_scripts/20200217131245_re_index_existing_articles_with_approved.rb") - -describe DataUpdateScripts::ReIndexExistingArticlesWithApproved do - it "triggers a re-index on articles" do - expect(Article).to respond_to(:trigger_index) - end -end diff --git a/spec/models/article_spec.rb b/spec/models/article_spec.rb index 22e86274e..abf8e575e 100644 --- a/spec/models/article_spec.rb +++ b/spec/models/article_spec.rb @@ -613,13 +613,6 @@ RSpec.describe Article, type: :model do end end - describe "#index_id" do - it "is equal to articles-ID" do - # NOTE: we shouldn't test private things but cheating a bit for Algolia here - expect(article.send(:index_id)).to eq("articles-#{article.id}") - end - end - describe ".seo_boostable" do let!(:top_article) do create(:article, organic_page_views_past_month_count: 20, score: 30, tags: "good, greatalicious", user: user) @@ -651,60 +644,6 @@ RSpec.describe Article, type: :model do end end - context "when indexing and deindexing" do - it "deindexes unpublished article from Article index" do - sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, args: [described_class.algolia_index_name, article.id]) do - article.update(body_markdown: "---\ntitle: Title\npublished: false\ndescription:\ntags: one\n---\n\n") - end - end - - it "deindexes unpublished article from searchables index" do - sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, args: ["searchables_#{Rails.env}", article.index_id]) do - article.update(body_markdown: "---\ntitle: Title\npublished: false\ndescription:\ntags: one\n---\n\n") - end - end - - it "deindexes unpublished article from ordered_articles index" do - sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, args: ["ordered_articles_#{Rails.env}", article.index_id]) do - article.update(body_markdown: "---\ntitle: Title\npublished: false\ndescription:\ntags: one\n---\n\n") - end - end - - it "deindexes hiring article from Article index" do - sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, args: [described_class.algolia_index_name, article.id]) do - article.update(body_markdown: "---\ntitle: Title\npublished: true\ndescription:\ntags: hiring\n---\n\n") - end - end - - it "deindexes hiring article from searchables index" do - sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, args: ["searchables_#{Rails.env}", article.index_id]) do - article.update(body_markdown: "---\ntitle: Title\npublished: true\ndescription:\ntags: hiring\n---\n\n") - end - end - - it "deindexes hiring article from ordered_articles index" do - sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, args: ["ordered_articles_#{Rails.env}", article.index_id]) do - article.update(body_markdown: "---\ntitle: Title\npublished: true\ndescription:\ntags: hiring\n---\n\n") - end - end - - it "indexes published non-hiring article" do - sidekiq_assert_enqueued_with(job: Search::IndexWorker, args: ["Article", article.id]) do - article.update(published: false) - end - end - - it "triggers auto removal from index on destroy" do - article = create(:article) - - allow(article).to receive(:remove_from_index!) - allow(article).to receive(:delete_related_objects) - article.destroy - expect(article).to have_received(:remove_from_index!) - expect(article).to have_received(:delete_related_objects) - end - end - context "when callbacks are triggered before save" do it "assigns path on save" do expect(article.path).to eq("/#{article.username}/#{article.slug}")