-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
relatable.rb
92 lines (73 loc) · 2.34 KB
/
relatable.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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
left_joins(:sdg_review).merge(SDG::Review.where(id: nil))
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 sdg_related_list
sdg_goals.order(:code).map do |goal|
[goal, sdg_global_targets.where(goal: goal).sort]
end.flatten.map(&:code).join(", ")
end
def sdg_related_list=(codes)
target_codes, goal_codes = codes.tr(" ", "").split(",").partition { |code| code.include?(".") }
targets = target_codes.map { |code| SDG::Target[code] }
goals = goal_codes.map { |code| SDG::Goal[code] }
transaction do
self.sdg_global_targets = targets
self.sdg_goals = (targets.map(&:goal) + goals).uniq
end
end
end