So now we know where to use the `where.missing` method which was introduced in Rails 6.1. Note this rule didn't detect all cases where the new method can be used.
94 lines
2.5 KiB
Ruby
94 lines
2.5 KiB
Ruby
module SDG::Relatable
|
|
extend ActiveSupport::Concern
|
|
|
|
included do
|
|
has_many :sdg_relations, as: :relatable, dependent: :destroy, class_name: "SDG::Relation"
|
|
|
|
%w[SDG::Goal SDG::LocalTarget].each do |sdg_type|
|
|
has_many sdg_type.constantize.table_name.to_sym,
|
|
through: :sdg_relations,
|
|
source: :related_sdg,
|
|
source_type: sdg_type
|
|
end
|
|
has_many :sdg_global_targets,
|
|
through: :sdg_relations,
|
|
source: :related_sdg,
|
|
source_type: "SDG::Target"
|
|
|
|
has_one :sdg_review, as: :relatable, dependent: :destroy, class_name: "SDG::Review"
|
|
end
|
|
|
|
class_methods do
|
|
def by_goal(code)
|
|
by_sdg_related(:sdg_goals, code)
|
|
end
|
|
|
|
def by_target(code)
|
|
if SDG::Target.find_by(code: code)
|
|
by_sdg_related(:sdg_global_targets, code)
|
|
else
|
|
by_sdg_related(:sdg_local_targets, code)
|
|
end
|
|
end
|
|
|
|
def by_sdg_related(association, code)
|
|
return all if code.blank?
|
|
|
|
sdg_class = reflect_on_association(association).options[:source_type].constantize
|
|
|
|
joins(association).merge(sdg_class.where(code: code))
|
|
end
|
|
|
|
def sdg_reviewed
|
|
joins(:sdg_review)
|
|
end
|
|
|
|
def pending_sdg_review
|
|
where.missing(:sdg_review)
|
|
end
|
|
end
|
|
|
|
def related_sdgs
|
|
sdg_relations.map(&:related_sdg)
|
|
end
|
|
|
|
def sdg_targets
|
|
sdg_global_targets + sdg_local_targets
|
|
end
|
|
|
|
def sdg_targets=(targets)
|
|
global_targets, local_targets = targets.partition { |target| target.class.name == "SDG::Target" }
|
|
|
|
transaction do
|
|
self.sdg_global_targets = global_targets
|
|
self.sdg_local_targets = local_targets
|
|
end
|
|
end
|
|
|
|
def sdg_goal_list
|
|
sdg_goals.order(:code).map(&:code).join(", ")
|
|
end
|
|
|
|
def sdg_target_list
|
|
sdg_targets.sort.map(&:code).join(", ")
|
|
end
|
|
|
|
def related_sdg_list
|
|
related_sdgs.sort.map(&:code).join(", ")
|
|
end
|
|
|
|
def related_sdg_list=(codes)
|
|
target_codes, goal_codes = codes.tr(" ", "").split(",").partition { |code| code.include?(".") }
|
|
local_targets_codes, global_targets_codes = target_codes.partition { |code| code.split(".")[2] }
|
|
global_targets = global_targets_codes.map { |code| SDG::Target[code] }
|
|
local_targets = local_targets_codes.map { |code| SDG::LocalTarget[code] }
|
|
goals = goal_codes.map { |code| SDG::Goal[code] }
|
|
|
|
transaction do
|
|
self.sdg_local_targets = local_targets
|
|
self.sdg_global_targets = global_targets
|
|
self.sdg_goals = (global_targets.map(&:goal) + local_targets.map(&:goal) + goals).uniq
|
|
end
|
|
end
|
|
end
|