[deploy] Remove Algolia from Article Model (#7540)
This commit is contained in:
parent
883eb170de
commit
ee373fa6c0
7 changed files with 2 additions and 169 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ module Articles
|
|||
return unless article
|
||||
|
||||
article.update_score
|
||||
article.index!
|
||||
article.index_to_elasticsearch_inline
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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}")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue