Merge pull request #4342 from consul/sdg_sort_performance

Improve performance sorting SDG records
This commit is contained in:
Javi Martín
2021-01-30 17:42:27 +01:00
committed by GitHub
4 changed files with 17 additions and 53 deletions

View File

@@ -1,5 +1,6 @@
module SDG::Related module SDG::Related
extend ActiveSupport::Concern extend ActiveSupport::Concern
include Comparable
RELATABLE_TYPES = %w[ RELATABLE_TYPES = %w[
Budget::Investment Budget::Investment
@@ -23,4 +24,20 @@ module SDG::Related
def relatables def relatables
relations.map(&:relatable) relations.map(&:relatable)
end end
def <=>(goal_or_target)
if goal_or_target.class.ancestors.include?(SDG::Related)
subcodes <=> goal_or_target.subcodes
end
end
def subcodes
code.to_s.split(".").map do |subcode|
if subcode.to_i.positive?
subcode.to_i
else
subcode.to_i(36) * 1000
end
end
end
end end

View File

@@ -1,5 +1,4 @@
class SDG::Goal < ApplicationRecord class SDG::Goal < ApplicationRecord
include Comparable
include SDG::Related include SDG::Related
validates :code, presence: true, uniqueness: true, inclusion: { in: 1..17 } validates :code, presence: true, uniqueness: true, inclusion: { in: 1..17 }
@@ -19,14 +18,6 @@ class SDG::Goal < ApplicationRecord
I18n.t("sdg.goals.goal_#{code}.description") I18n.t("sdg.goals.goal_#{code}.description")
end end
def <=>(goal_or_target)
if goal_or_target.class == self.class
code <=> goal_or_target.code
elsif goal_or_target.respond_to?(:goal)
[self, -1] <=> [goal_or_target.goal, 1]
end
end
def self.[](code) def self.[](code)
find_by!(code: code) find_by!(code: code)
end end

View File

@@ -1,5 +1,4 @@
class SDG::LocalTarget < ApplicationRecord class SDG::LocalTarget < ApplicationRecord
include Comparable
include SDG::Related include SDG::Related
translates :title, touch: true translates :title, touch: true
@@ -23,26 +22,8 @@ class SDG::LocalTarget < ApplicationRecord
find_by!(code: code) find_by!(code: code)
end end
def <=>(goal_or_target)
if goal_or_target.class == self.class
[target, numeric_subcode] <=> [goal_or_target.target, goal_or_target.numeric_subcode]
elsif [target.class, goal.class].include?(goal_or_target.class)
-1 * (goal_or_target <=> self)
end
end
protected
def numeric_subcode
subcode.to_i
end
private private
def subcode
code.split(".").last
end
def set_related_goal def set_related_goal
self.goal ||= target&.goal self.goal ||= target&.goal
end end

View File

@@ -1,5 +1,4 @@
class SDG::Target < ApplicationRecord class SDG::Target < ApplicationRecord
include Comparable
include SDG::Related include SDG::Related
validates :code, presence: true, uniqueness: true validates :code, presence: true, uniqueness: true
@@ -12,37 +11,13 @@ class SDG::Target < ApplicationRecord
I18n.t("sdg.goals.goal_#{goal.code}.targets.target_#{code_key}.title") I18n.t("sdg.goals.goal_#{goal.code}.targets.target_#{code_key}.title")
end end
def <=>(goal_or_target)
if goal_or_target.class == self.class
[goal.code, numeric_subcode] <=> [goal_or_target.goal.code, goal_or_target.numeric_subcode]
elsif goal_or_target.class == goal.class
-1 * (goal_or_target <=> self)
elsif goal_or_target.class.name == "SDG::LocalTarget"
[self, -1] <=> [goal_or_target.target, 1]
end
end
def self.[](code) def self.[](code)
find_by!(code: code) find_by!(code: code)
end end
protected
def numeric_subcode
if subcode.to_i > 0
subcode.to_i
else
subcode.to_i(36) * 1000
end
end
private private
def code_key def code_key
code.gsub(".", "_").upcase code.gsub(".", "_").upcase
end end
def subcode
code.split(".").last
end
end end