From ff96fcc0c2690f58c97ecccb0c166f072f6a0865 Mon Sep 17 00:00:00 2001
From: pabois <pierreandre.boissinot@noesya.coop>
Date: Mon, 25 Apr 2022 17:27:21 +0200
Subject: [PATCH] is_author is now denormalized (and used in filters)

---
 .../admin/university/people_controller.rb          |  1 +
 app/models/communication/website/post.rb           |  9 +++++++++
 app/models/university/person.rb                    | 12 ++++++------
 app/models/university/person/administrator.rb      |  1 +
 app/models/university/person/alumnus.rb            |  1 +
 app/models/university/person/author.rb             |  1 +
 app/models/university/person/researcher.rb         |  1 +
 app/models/university/person/teacher.rb            |  1 +
 app/services/filters/admin/university/people.rb    |  1 +
 .../communication/website/posts/index.html.erb     |  2 +-
 ...425150705_add_is_author_to_university_people.rb |  5 +++++
 db/schema.rb                                       |  3 ++-
 lib/tasks/app.rake                                 | 14 +++-----------
 13 files changed, 33 insertions(+), 19 deletions(-)
 create mode 100644 db/migrate/20220425150705_add_is_author_to_university_people.rb

diff --git a/app/controllers/admin/university/people_controller.rb b/app/controllers/admin/university/people_controller.rb
index b3ef36fb4..bdc9ee2d2 100644
--- a/app/controllers/admin/university/people_controller.rb
+++ b/app/controllers/admin/university/people_controller.rb
@@ -5,6 +5,7 @@ class Admin::University::PeopleController < Admin::University::ApplicationContro
 
 
   has_scope :for_search_term
+  has_scope :for_role
 
   def index
     @people = apply_scopes(@people).ordered.page(params[:page])
diff --git a/app/models/communication/website/post.rb b/app/models/communication/website/post.rb
index 71ca1ad6e..14cda1e87 100644
--- a/app/models/communication/website/post.rb
+++ b/app/models/communication/website/post.rb
@@ -63,6 +63,7 @@ class Communication::Website::Post < ApplicationRecord
   validates :title, presence: true
 
   before_validation :set_published_at, if: :published_changed?
+  after_save_commit :update_authors_statuses!, if: :saved_change_to_author_id?
 
   scope :published, -> { where(published: true) }
   scope :ordered, -> { order(published_at: :desc, created_at: :desc) }
@@ -123,4 +124,12 @@ class Communication::Website::Post < ApplicationRecord
   def inherited_blob_ids
     [best_featured_image&.blob_id]
   end
+
+  def update_authors_statuses!
+    old_author = University::Person.find_by(id: author_id_before_last_save)
+    if old_author && old_author.communication_website_posts.none?
+      old_author.update_and_sync(is_author: false)
+    end
+    author.update_and_sync(is_author: true) if author_id
+  end
 end
diff --git a/app/models/university/person.rb b/app/models/university/person.rb
index 04132d7c2..b92e02457 100644
--- a/app/models/university/person.rb
+++ b/app/models/university/person.rb
@@ -11,6 +11,7 @@
 #  habilitation      :boolean          default(FALSE)
 #  is_administration :boolean
 #  is_alumnus        :boolean          default(FALSE)
+#  is_author         :boolean
 #  is_researcher     :boolean
 #  is_teacher        :boolean
 #  last_name         :string
@@ -44,6 +45,8 @@ class University::Person < ApplicationRecord
   include WithPicture
   include WithEducation
 
+  LIST_OF_ROLES = [:administration, :teacher, :researcher, :alumnus, :author].freeze
+
   has_summernote :biography
 
   belongs_to :user, optional: true
@@ -108,6 +111,8 @@ class University::Person < ApplicationRecord
   scope :teachers,        -> { where(is_teacher: true) }
   scope :researchers,     -> { where(is_researcher: true) }
   scope :alumni,          -> { where(is_alumnus: true) }
+  scope :for_role, -> (role) { where("is_#{role}": true) }
+
   scope :for_search_term, -> (term) {
     where("
       unaccent(concat(university_people.first_name, ' ', university_people.last_name)) ILIKE unaccent(:term) OR
@@ -129,16 +134,11 @@ class University::Person < ApplicationRecord
   end
 
   def roles
-    [:administration, :teacher, :researcher, :alumnus, :author].reject do |role|
+    LIST_OF_ROLES.reject do |role|
       ! send "is_#{role}"
     end
   end
 
-  # TODO denormalize
-  def is_author
-    communication_website_posts.any?
-  end
-
   def websites
     university.communication_websites
   end
diff --git a/app/models/university/person/administrator.rb b/app/models/university/person/administrator.rb
index f5fda080a..8205a3fb2 100644
--- a/app/models/university/person/administrator.rb
+++ b/app/models/university/person/administrator.rb
@@ -11,6 +11,7 @@
 #  habilitation      :boolean          default(FALSE)
 #  is_administration :boolean
 #  is_alumnus        :boolean          default(FALSE)
+#  is_author         :boolean
 #  is_researcher     :boolean
 #  is_teacher        :boolean
 #  last_name         :string
diff --git a/app/models/university/person/alumnus.rb b/app/models/university/person/alumnus.rb
index 06c70f24c..cf5bf3a3d 100644
--- a/app/models/university/person/alumnus.rb
+++ b/app/models/university/person/alumnus.rb
@@ -11,6 +11,7 @@
 #  habilitation      :boolean          default(FALSE)
 #  is_administration :boolean
 #  is_alumnus        :boolean          default(FALSE)
+#  is_author         :boolean
 #  is_researcher     :boolean
 #  is_teacher        :boolean
 #  last_name         :string
diff --git a/app/models/university/person/author.rb b/app/models/university/person/author.rb
index 67dda6a6e..e18ceeef7 100644
--- a/app/models/university/person/author.rb
+++ b/app/models/university/person/author.rb
@@ -11,6 +11,7 @@
 #  habilitation      :boolean          default(FALSE)
 #  is_administration :boolean
 #  is_alumnus        :boolean          default(FALSE)
+#  is_author         :boolean
 #  is_researcher     :boolean
 #  is_teacher        :boolean
 #  last_name         :string
diff --git a/app/models/university/person/researcher.rb b/app/models/university/person/researcher.rb
index 8fffe668f..307043e55 100644
--- a/app/models/university/person/researcher.rb
+++ b/app/models/university/person/researcher.rb
@@ -11,6 +11,7 @@
 #  habilitation      :boolean          default(FALSE)
 #  is_administration :boolean
 #  is_alumnus        :boolean          default(FALSE)
+#  is_author         :boolean
 #  is_researcher     :boolean
 #  is_teacher        :boolean
 #  last_name         :string
diff --git a/app/models/university/person/teacher.rb b/app/models/university/person/teacher.rb
index df1e88803..8a6ef74e9 100644
--- a/app/models/university/person/teacher.rb
+++ b/app/models/university/person/teacher.rb
@@ -11,6 +11,7 @@
 #  habilitation      :boolean          default(FALSE)
 #  is_administration :boolean
 #  is_alumnus        :boolean          default(FALSE)
+#  is_author         :boolean
 #  is_researcher     :boolean
 #  is_teacher        :boolean
 #  last_name         :string
diff --git a/app/services/filters/admin/university/people.rb b/app/services/filters/admin/university/people.rb
index 6ad19dca1..515697eaf 100644
--- a/app/services/filters/admin/university/people.rb
+++ b/app/services/filters/admin/university/people.rb
@@ -3,6 +3,7 @@ module Filters
     def initialize(user)
       super
       add_search
+      add :for_role, ::University::Person::LIST_OF_ROLES.map { |r| { to_s: I18n.t("activerecord.attributes.university/person.#{r}"), id: r } }, I18n.t('filters.attributes.role')
     end
   end
 end
diff --git a/app/views/admin/communication/website/posts/index.html.erb b/app/views/admin/communication/website/posts/index.html.erb
index 814a431bf..e13ed71d7 100644
--- a/app/views/admin/communication/website/posts/index.html.erb
+++ b/app/views/admin/communication/website/posts/index.html.erb
@@ -2,7 +2,7 @@
 
 <%= render 'admin/communication/websites/sidebar' do %>
   <div class="card">
-    <%= render 'admin/communication/website/posts/list', posts: @posts, hide_author: true %>
+    <%= render 'admin/communication/website/posts/list', posts: @posts %>
     <% if @posts.total_pages > 1 %>
       <div class="card-footer">
         <%= paginate @posts, theme: 'bootstrap-5' %>
diff --git a/db/migrate/20220425150705_add_is_author_to_university_people.rb b/db/migrate/20220425150705_add_is_author_to_university_people.rb
new file mode 100644
index 000000000..287c2cb05
--- /dev/null
+++ b/db/migrate/20220425150705_add_is_author_to_university_people.rb
@@ -0,0 +1,5 @@
+class AddIsAuthorToUniversityPeople < ActiveRecord::Migration[6.1]
+  def change
+    add_column :university_people, :is_author, :boolean
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 9344a9d83..7df6f03f9 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 2022_04_21_093107) do
+ActiveRecord::Schema.define(version: 2022_04_25_150705) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "pgcrypto"
@@ -671,6 +671,7 @@ ActiveRecord::Schema.define(version: 2022_04_21_093107) do
     t.string "linkedin"
     t.boolean "is_alumnus", default: false
     t.text "description_short"
+    t.boolean "is_author"
     t.index ["university_id"], name: "index_university_people_on_university_id"
     t.index ["user_id"], name: "index_university_people_on_user_id"
   end
diff --git a/lib/tasks/app.rake b/lib/tasks/app.rake
index 616dfe0f4..c83caba11 100644
--- a/lib/tasks/app.rake
+++ b/lib/tasks/app.rake
@@ -8,17 +8,9 @@ namespace :app do
 
   desc 'Fix things'
   task fix: :environment do
-    Communication::Block.where(template: 'partners').find_each do |partner|
-      next if partner.data.nil?
-      data = partner.data
-      next unless data.has_key? 'elements'
-      elements = data['elements']
-      next if elements.none?
-      first = elements.first
-      next unless first.has_key? 'partners'
-      partner.title = first['title']
-      partner.data['elements'] = first['partners']
-      partner.save
+    University::Person.find_each do |person|
+      person.is_author = person.communication_website_posts.any?
+      person.save
     end
   end
 
-- 
GitLab