[deploy] refactor data syncing methods to use a base class and take a single argument (#7204)

This commit is contained in:
Molly Struve 2020-04-10 11:11:35 -05:00 committed by GitHub
parent c627f4e98a
commit 10b094b4b6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 87 additions and 131 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View 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

View file

@ -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

View file

@ -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

View file

@ -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

View 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

View file

@ -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

View file

@ -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