big speedup in syncing via caching/reducing queries (#610)

This commit is contained in:
Tom Carchrae 2019-01-14 17:56:21 -08:00 committed by Patrick Gansterer
parent 31689dfb75
commit 7e88798778
3 changed files with 19 additions and 7 deletions

View file

@ -154,7 +154,7 @@ class Article < ActiveRecord::Base
# to get the correspondent shared article # to get the correspondent shared article
def shared_article(supplier = self.supplier) def shared_article(supplier = self.supplier)
self.order_number.blank? and return nil self.order_number.blank? and return nil
@shared_article ||= supplier.shared_supplier.shared_articles.find_by_number(self.order_number) rescue nil @shared_article ||= supplier.shared_supplier.find_article_by_number(self.order_number) rescue nil
end end
# convert units in foodcoop-size # convert units in foodcoop-size

View file

@ -1,5 +1,5 @@
class SharedSupplier < ActiveRecord::Base class SharedSupplier < ActiveRecord::Base
# connect to database from sharedLists-Application # connect to database from sharedLists-Application
SharedSupplier.establish_connection(FoodsoftConfig[:shared_lists]) SharedSupplier.establish_connection(FoodsoftConfig[:shared_lists])
# set correct table_name in external DB # set correct table_name in external DB
@ -8,6 +8,16 @@ class SharedSupplier < ActiveRecord::Base
has_many :suppliers has_many :suppliers
has_many :shared_articles, :foreign_key => :supplier_id has_many :shared_articles, :foreign_key => :supplier_id
def find_article_by_number(order_number)
# note that `shared_articles` uses number instead order_number
cached_articles.detect { |a| a.number == order_number }
end
def cached_articles
@cached_articles ||= shared_articles.all
end
# These set of attributes are used to autofill attributes of new supplier, # These set of attributes are used to autofill attributes of new supplier,
# when created by import from shared supplier feature. # when created by import from shared supplier feature.
def autofill_attributes def autofill_attributes

View file

@ -32,11 +32,13 @@ class Supplier < ActiveRecord::Base
# also returns an array with new articles, which should be added (depending on shared_sync_method) # also returns an array with new articles, which should be added (depending on shared_sync_method)
def sync_all def sync_all
updated_article_pairs, outlisted_articles, new_articles = [], [], [] updated_article_pairs, outlisted_articles, new_articles = [], [], []
existing_articles = Set.new
for article in articles.undeleted for article in articles.undeleted
# try to find the associated shared_article # try to find the associated shared_article
shared_article = article.shared_article(self) shared_article = article.shared_article(self)
if shared_article # article will be updated if shared_article # article will be updated
existing_articles.add(shared_article.id)
unequal_attributes = article.shared_article_changed?(self) unequal_attributes = article.shared_article_changed?(self)
unless unequal_attributes.blank? # skip if shared_article has not been changed unless unequal_attributes.blank? # skip if shared_article has not been changed
article.attributes = unequal_attributes article.attributes = unequal_attributes
@ -51,11 +53,11 @@ class Supplier < ActiveRecord::Base
end end
# Find any new articles, unless the import is manual # Find any new articles, unless the import is manual
unless shared_sync_method == 'import' unless shared_sync_method == 'import'
for shared_article in shared_supplier.shared_articles shared_supplier
unless articles.undeleted.find_by_order_number(shared_article.number) .shared_articles
new_articles << shared_article.build_new_article(self) .where(available: true)
end .where.not(id: existing_articles)
end .each { |shared_article| new_articles << shared_article.build_new_article(self) }
end end
return [updated_article_pairs, outlisted_articles, new_articles] return [updated_article_pairs, outlisted_articles, new_articles]
end end