From 90a8420fcf24b809dc4977c1d02e712ca62814e2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Gaya?= <sebastien.gaya@gmail.com>
Date: Mon, 22 Apr 2024 11:56:27 +0200
Subject: [PATCH] Optimization backlinks (#1833)

* optimization backlink

* fix

* fix
---
 .../block/template/organization.rb            | 10 +++++-
 .../block/template/organization/element.rb    |  4 +++
 .../communication/block/template/person.rb    | 10 +++++-
 .../block/template/person/element.rb          |  4 +++
 app/models/concerns/backlinkable.rb           | 32 +++++++++++++------
 5 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/app/models/communication/block/template/organization.rb b/app/models/communication/block/template/organization.rb
index ac33cfa56..a7534aac8 100644
--- a/app/models/communication/block/template/organization.rb
+++ b/app/models/communication/block/template/organization.rb
@@ -18,8 +18,16 @@ class Communication::Block::Template::Organization < Communication::Block::Templ
   def organizations
     @organizations ||= elements.collect(&:organization).compact.uniq
   end
-  
+
+  def organization_ids
+    @organization_ids ||= @elements.collect(&:organization_id).compact.uniq
+  end
+
   def children
     organizations
   end
+
+  def children_ids
+    organization_ids
+  end
 end
diff --git a/app/models/communication/block/template/organization/element.rb b/app/models/communication/block/template/organization/element.rb
index 6ef7c4c8f..7a2f91b1e 100644
--- a/app/models/communication/block/template/organization/element.rb
+++ b/app/models/communication/block/template/organization/element.rb
@@ -9,6 +9,10 @@ class Communication::Block::Template::Organization::Element < Communication::Blo
     id_component.organization
   end
 
+  def organization_id
+    id_component.data
+  end
+
   def best_name
     organization ? organization.name : name
   end
diff --git a/app/models/communication/block/template/person.rb b/app/models/communication/block/template/person.rb
index 8cfbb0255..79862d1a4 100644
--- a/app/models/communication/block/template/person.rb
+++ b/app/models/communication/block/template/person.rb
@@ -18,8 +18,16 @@ class Communication::Block::Template::Person < Communication::Block::Template::B
   def people
     @people ||= elements.collect(&:person).compact.uniq
   end
-  
+
+  def person_ids
+    @person_ids ||= @elements.collect(&:person_id).compact.uniq
+  end
+
   def children
     people
   end
+
+  def children_ids
+    person_ids
+  end
 end
diff --git a/app/models/communication/block/template/person/element.rb b/app/models/communication/block/template/person/element.rb
index 066d4c85b..6482cac6f 100644
--- a/app/models/communication/block/template/person/element.rb
+++ b/app/models/communication/block/template/person/element.rb
@@ -6,4 +6,8 @@ class Communication::Block::Template::Person::Element < Communication::Block::Te
   def person
     id_component.person
   end
+
+  def person_id
+    id_component.data
+  end
 end
diff --git a/app/models/concerns/backlinkable.rb b/app/models/concerns/backlinkable.rb
index 4a5b6b238..f1120f1c7 100644
--- a/app/models/concerns/backlinkable.rb
+++ b/app/models/concerns/backlinkable.rb
@@ -3,7 +3,7 @@ module Backlinkable
 
   def backlinks_pages(website)
     backlinks(
-      Communication::Website::Page,
+      "Communication::Website::Page",
       website
     )
     .reject { |page| page.is_special_page? }
@@ -11,14 +11,14 @@ module Backlinkable
 
   def backlinks_posts(website)
     backlinks(
-      Communication::Website::Post,
+      "Communication::Website::Post",
       website
     )
   end
 
   def backlinks_agenda_events(website)
     backlinks(
-      Communication::Website::Agenda::Event,
+      "Communication::Website::Agenda::Event",
       website
     )
   end
@@ -26,15 +26,29 @@ module Backlinkable
   protected
 
   def backlinks(kind, website)
-    backlinks_blocks(website).published.map { |block|
-      block.about if backlink_in_block?(block, kind)
+    backlinks_object_ids = published_backlinks_blocks(website).map { |block|
+      block.about_id if backlink_in_block?(block, kind, website)
     }.compact
+    kind.safe_constantize.published.where(communication_website_id: website.id, id: backlinks_object_ids)
   end
 
-  def backlink_in_block?(block, kind)
-    block.about.is_a?(kind) && # Correct kind
-    self.in?(block.template.children) && # Mentioning self
-    block.about.published? # About published
+  def backlink_in_block?(block, kind, website)
+    block.about_type == kind && # Correct kind
+    block.about_id.in?(published_backlinks_object_ids(website, kind)) && # About published
+    self.id.in?(block.template.children_ids) # Mentioning self
+  end
+
+  def published_backlinks_object_ids(website, kind)
+    # Memoize to avoid multiple queries for the same website and kind
+    @published_backlinks_object_ids ||= {}
+    @published_backlinks_object_ids[website.id] ||= {}
+    @published_backlinks_object_ids[website.id][kind] ||= kind.safe_constantize.published.where(communication_website_id: website.id).pluck(:id)
+  end
+
+  def published_backlinks_blocks(website)
+    # Memoize to avoid multiple queries for the same website
+    @published_backlinks_blocks ||= {}
+    @published_backlinks_blocks[website.id] ||= backlinks_blocks(website).published
   end
 
   def backlinks_blocks(website)
-- 
GitLab