From 8e7766a7aae9fa191894e4323257d9e61b1bc940 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Gaya?= <sebastien.gaya@gmail.com>
Date: Thu, 23 Feb 2023 15:42:04 +0100
Subject: [PATCH] sanitizable refactor

---
 app/models/concerns/sanitizable.rb | 49 +++++++++++++++++++++++-------
 app/models/research/laboratory.rb  |  2 +-
 2 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/app/models/concerns/sanitizable.rb b/app/models/concerns/sanitizable.rb
index 83f0cdaea..ddf47b662 100644
--- a/app/models/concerns/sanitizable.rb
+++ b/app/models/concerns/sanitizable.rb
@@ -6,19 +6,46 @@ module Sanitizable
     before_validation :sanitize_fields
 
     def sanitize_fields
-      attributes_to_sanitize = self.class.columns_hash.map { |name,value| [name, value.type] }
-                                                      .to_h
-                                                      .select { |attr_name, attr_type|
-                                                        [:string, :text].include?(attr_type) && public_send(attr_name).present?
-                                                      }
-                                                      .reject { |attr_name, _|
-                                                        attr_name.ends_with?('_type') # Reject polymorphic type
-                                                      }
-
-      attributes_to_sanitize.each do |attr_name, attr_type|
-        public_send "#{attr_name}=", Osuny::Sanitizer.sanitize(public_send(attr_name), attr_type)
+      attributes_to_sanitize.each do |attribute_name, attribute_type|
+        dangerous_value = public_send attribute_name
+        sanitized_value = Osuny::Sanitizer.sanitize(dangerous_value, attribute_type)
+        public_send "#{attribute_name}=", sanitized_value
       end
     end
 
+    protected
+
+    #  {
+    #   "description" => :text
+    #  }
+    def attributes_to_sanitize
+      attributes_with_type.select { |attribute_name, attribute_type|
+        should_sanitize?(attribute_name, attribute_type)
+      }
+    end
+
+    def should_sanitize?(attribute_name, attribute_type)
+      # We filter the attributes with "string" or "text" SQL type.
+      return false unless [:string, :text].include?(attribute_type)
+      # We filter the text attributes by their presence.
+      return false unless public_send(attribute_name).present?
+      # We filter the attributes which end with "_type" (polymorphic attributes)
+      return false if attribute_name.ends_with?('_type')
+      true
+    end
+
+    #  {
+    #   "id" => :uuid,
+    #   "description" => :text,
+    #   "position" => :integer,
+    #   "target_type" => :string,
+    #   "created_at" => :datetime,
+    #   "updated_at" => :datetime,
+    #   "target_id" => :uuid,
+    #   "university_id" => :uuid
+    #  }
+    def attributes_with_type
+      self.class.columns_hash.map { |name, value| [name, value.type] }.to_h
+    end
   end
 end
diff --git a/app/models/research/laboratory.rb b/app/models/research/laboratory.rb
index d5e261d49..a70817fe9 100644
--- a/app/models/research/laboratory.rb
+++ b/app/models/research/laboratory.rb
@@ -21,9 +21,9 @@
 #  fk_rails_f61d27545f  (university_id => universities.id)
 #
 class Research::Laboratory < ApplicationRecord
+  include Aboutable
   include Sanitizable
   include WithGit
-  include Aboutable
 
   belongs_to  :university
   has_many    :websites,
-- 
GitLab