[deploy] refactor data syncing methods to use a base class and take a single argument (#7204)
This commit is contained in:
parent
c627f4e98a
commit
10b094b4b6
10 changed files with 87 additions and 131 deletions
|
|
@ -24,6 +24,6 @@ module Searchable
|
|||
end
|
||||
|
||||
def sync_related_elasticsearch_docs
|
||||
self.class::DATA_SYNC_CLASS.new(self, saved_changes).call
|
||||
self.class::DATA_SYNC_CLASS.new(self).call
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -142,6 +142,6 @@ class Organization < ApplicationRecord
|
|||
end
|
||||
|
||||
def sync_related_elasticsearch_docs
|
||||
DataSync::Elasticsearch::Organization.new(self, saved_changes).call
|
||||
DataSync::Elasticsearch::Organization.new(self).call
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
module DataSync
|
||||
module Elasticsearch
|
||||
class Article
|
||||
class Article < Base
|
||||
RELATED_DOCS = %i[
|
||||
reactions
|
||||
].freeze
|
||||
|
||||
SHARED_ARTICLE_FIELDS = %i[
|
||||
SHARED_FIELDS = %i[
|
||||
body_markdown
|
||||
path
|
||||
published
|
||||
|
|
@ -14,18 +14,11 @@ module DataSync
|
|||
title
|
||||
].freeze
|
||||
|
||||
attr_accessor :article, :updated_fields
|
||||
|
||||
def initialize(article, updated_fields)
|
||||
@article = article
|
||||
@updated_fields = updated_fields.deep_symbolize_keys
|
||||
end
|
||||
|
||||
def call
|
||||
return unless sync_needed?
|
||||
private
|
||||
|
||||
def sync_related_documents
|
||||
RELATED_DOCS.each do |relation_name|
|
||||
if article.published
|
||||
if updated_record.published
|
||||
send(relation_name).find_each(&:index_to_elasticsearch)
|
||||
elsif updated_fields.key?(:published)
|
||||
send(relation_name).find_each(&:remove_from_elasticsearch)
|
||||
|
|
@ -33,14 +26,12 @@ module DataSync
|
|||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sync_needed?
|
||||
updated_fields.slice(*SHARED_ARTICLE_FIELDS).any? && reactions.any?
|
||||
updated_fields.slice(*SHARED_FIELDS).any? && reactions.any?
|
||||
end
|
||||
|
||||
def reactions
|
||||
article.reactions.readinglist
|
||||
updated_record.reactions.readinglist
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
33
app/services/data_sync/elasticsearch/base.rb
Normal file
33
app/services/data_sync/elasticsearch/base.rb
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
module DataSync
|
||||
module Elasticsearch
|
||||
class Base
|
||||
attr_reader :updated_record
|
||||
|
||||
def initialize(updated_record)
|
||||
@updated_record = updated_record
|
||||
end
|
||||
|
||||
def call
|
||||
return unless sync_needed?
|
||||
|
||||
sync_related_documents
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sync_needed?
|
||||
updated_fields.slice(*self.class::SHARED_FIELDS).any?
|
||||
end
|
||||
|
||||
def sync_related_documents
|
||||
self.class::RELATED_DOCS.each do |relation_name|
|
||||
send(relation_name).find_each(&:index_to_elasticsearch)
|
||||
end
|
||||
end
|
||||
|
||||
def updated_fields
|
||||
updated_record.saved_changes
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,38 +1,17 @@
|
|||
module DataSync
|
||||
module Elasticsearch
|
||||
class Organization
|
||||
class Organization < Base
|
||||
RELATED_DOCS = %i[
|
||||
articles
|
||||
].freeze
|
||||
|
||||
SHARED_TAG_FIELDS = %i[
|
||||
SHARED_FIELDS = %i[
|
||||
slug
|
||||
name
|
||||
profile_image
|
||||
].freeze
|
||||
|
||||
attr_accessor :organization, :updated_fields
|
||||
|
||||
delegate :articles, to: :@organization
|
||||
|
||||
def initialize(organization, updated_fields)
|
||||
@organization = organization
|
||||
@updated_fields = updated_fields.deep_symbolize_keys
|
||||
end
|
||||
|
||||
def call
|
||||
return unless sync_needed?
|
||||
|
||||
RELATED_DOCS.each do |relation_name|
|
||||
send(relation_name).find_each(&:index_to_elasticsearch)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sync_needed?
|
||||
updated_fields.slice(*SHARED_TAG_FIELDS).any?
|
||||
end
|
||||
delegate :articles, to: :@updated_record
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
module DataSync
|
||||
module Elasticsearch
|
||||
class User
|
||||
class User < Base
|
||||
RELATED_DOCS = %i[
|
||||
articles
|
||||
reactions
|
||||
|
|
@ -9,42 +9,23 @@ module DataSync
|
|||
comments
|
||||
].freeze
|
||||
|
||||
SHARED_USER_FIELDS = %i[
|
||||
SHARED_FIELDS = %i[
|
||||
username
|
||||
name
|
||||
pro
|
||||
profile_image_url
|
||||
].freeze
|
||||
|
||||
attr_accessor :user, :updated_fields
|
||||
|
||||
delegate :articles, :chat_channel_memberships, :comments, to: :@user
|
||||
|
||||
def initialize(user, updated_fields)
|
||||
@user = user
|
||||
@updated_fields = updated_fields.deep_symbolize_keys
|
||||
end
|
||||
|
||||
def call
|
||||
return unless sync_needed?
|
||||
|
||||
RELATED_DOCS.each do |relation_name|
|
||||
send(relation_name).find_each(&:index_to_elasticsearch)
|
||||
end
|
||||
end
|
||||
delegate :articles, :chat_channel_memberships, :comments, to: :@updated_record
|
||||
|
||||
private
|
||||
|
||||
def sync_needed?
|
||||
updated_fields.slice(*SHARED_USER_FIELDS).any?
|
||||
end
|
||||
|
||||
def reactions
|
||||
user.reactions.readinglist
|
||||
updated_record.reactions.readinglist
|
||||
end
|
||||
|
||||
def podcast_episodes
|
||||
PodcastEpisode.for_user(user)
|
||||
PodcastEpisode.for_user(updated_record)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,35 +3,21 @@ require "rails_helper"
|
|||
RSpec.describe DataSync::Elasticsearch::Article, type: :service do
|
||||
let(:article) { create(:article) }
|
||||
|
||||
describe "#call" do
|
||||
it "reindexes RELATED_DOCS when sync is needed " do
|
||||
syncer = described_class.new(article, title: %w[old_title new_title])
|
||||
described_class::RELATED_DOCS.each do |method_name|
|
||||
allow(syncer).to receive(method_name).and_call_original
|
||||
end
|
||||
syncer.call
|
||||
described_class::RELATED_DOCS.each do |method_name|
|
||||
expect(syncer).to have_received(method_name)
|
||||
end
|
||||
end
|
||||
|
||||
it "does not reindex when sync is not needed" do
|
||||
syncer = described_class.new(article, page_views_count: [nil, 1])
|
||||
described_class::RELATED_DOCS.each { |method_name| allow(syncer).to receive(method_name) }
|
||||
syncer.call
|
||||
described_class::RELATED_DOCS.each do |method_name|
|
||||
expect(syncer).not_to have_received(method_name)
|
||||
end
|
||||
end
|
||||
it "defines necessary constants" do
|
||||
expect(described_class::RELATED_DOCS).not_to be_nil
|
||||
expect(described_class::SHARED_FIELDS).not_to be_nil
|
||||
end
|
||||
|
||||
describe "#sync_related_documents" do
|
||||
it "removes docs from elasticsearch if article is unpublished" do
|
||||
allow(article).to receive(:saved_changes).and_return(published: [true, false])
|
||||
reaction = create(:reaction, reactable: article, category: "readinglist")
|
||||
sidekiq_perform_enqueued_jobs
|
||||
expect(reaction.elasticsearch_doc).not_to be_nil
|
||||
|
||||
article.update_column(:published, false)
|
||||
|
||||
described_class.new(article, published: [true, false]).call
|
||||
described_class.new(article).call
|
||||
sidekiq_perform_enqueued_jobs
|
||||
expect { reaction.elasticsearch_doc }.to raise_error(Search::Errors::Transport::NotFound)
|
||||
end
|
||||
|
|
|
|||
24
spec/services/data_sync/elasticsearch/base_spec.rb
Normal file
24
spec/services/data_sync/elasticsearch/base_spec.rb
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe DataSync::Elasticsearch::Base, type: :service do
|
||||
let!(:updated_record) { instance_double("Record", saved_changes: { name: %w[name1 name2] }) }
|
||||
let(:syncer) { described_class.new(updated_record) }
|
||||
|
||||
describe "#call" do
|
||||
before do
|
||||
stub_const("#{described_class}::SHARED_FIELDS", %i[name])
|
||||
allow(syncer).to receive(:sync_related_documents)
|
||||
end
|
||||
|
||||
it "syncs related_documents when sync is needed " do
|
||||
syncer.call
|
||||
expect(syncer).to have_received(:sync_related_documents)
|
||||
end
|
||||
|
||||
it "does not sync related_documents when sync is not needed" do
|
||||
allow(updated_record).to receive(:saved_changes).and_return(twitter_url: %w[url1 url2])
|
||||
syncer.call
|
||||
expect(syncer).not_to have_received(:sync_related_documents)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,27 +1,8 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe DataSync::Elasticsearch::Organization, type: :service do
|
||||
let!(:organization) { create(:organization) }
|
||||
|
||||
describe "#call" do
|
||||
it "reindexes RELATED_DOCS when sync is needed " do
|
||||
syncer = described_class.new(organization, name: %w[name1 name2])
|
||||
described_class::RELATED_DOCS.each do |method_name|
|
||||
allow(syncer).to receive(method_name).and_call_original
|
||||
end
|
||||
syncer.call
|
||||
described_class::RELATED_DOCS.each do |method_name|
|
||||
expect(syncer).to have_received(method_name)
|
||||
end
|
||||
end
|
||||
|
||||
it "does not reindex when sync is not needed" do
|
||||
syncer = described_class.new(organization, articles_count: [0, 1])
|
||||
described_class::RELATED_DOCS.each { |method_name| allow(syncer).to receive(method_name) }
|
||||
syncer.call
|
||||
described_class::RELATED_DOCS.each do |method_name|
|
||||
expect(syncer).not_to have_received(method_name)
|
||||
end
|
||||
end
|
||||
it "defines necessary constants" do
|
||||
expect(described_class::RELATED_DOCS).not_to be_nil
|
||||
expect(described_class::SHARED_FIELDS).not_to be_nil
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,27 +1,8 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe DataSync::Elasticsearch::User, type: :service do
|
||||
let!(:user) { create(:user) }
|
||||
|
||||
describe "#call" do
|
||||
it "reindexes RELATED_DOCS when sync is needed " do
|
||||
syncer = described_class.new(user, username: %w[name1 name2])
|
||||
described_class::RELATED_DOCS.each do |method_name|
|
||||
allow(syncer).to receive(method_name).and_call_original
|
||||
end
|
||||
syncer.call
|
||||
described_class::RELATED_DOCS.each do |method_name|
|
||||
expect(syncer).to have_received(method_name)
|
||||
end
|
||||
end
|
||||
|
||||
it "does not reindex when sync is not needed" do
|
||||
syncer = described_class.new(user, stackoverflow_url: [nil, "url"])
|
||||
described_class::RELATED_DOCS.each { |method_name| allow(syncer).to receive(method_name) }
|
||||
syncer.call
|
||||
described_class::RELATED_DOCS.each do |method_name|
|
||||
expect(syncer).not_to have_received(method_name)
|
||||
end
|
||||
end
|
||||
it "defines necessary constants" do
|
||||
expect(described_class::RELATED_DOCS).not_to be_nil
|
||||
expect(described_class::SHARED_FIELDS).not_to be_nil
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue