-
Notifications
You must be signed in to change notification settings - Fork 32
/
term.rb
107 lines (83 loc) · 2.86 KB
/
term.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# frozen_string_literal: true
module GobiertoCommon
class Term < ApplicationRecord
before_validation :calculate_level, :set_vocabulary
include GobiertoCommon::Sortable
include GobiertoCommon::ActsAsTree
include User::Subscribable
include GobiertoCommon::Sluggable
after_save :update_children_levels
before_destroy :free_children
before_validation :clear_parent_if_itself
belongs_to :vocabulary
has_many :terms, dependent: :nullify
belongs_to :parent_term, class_name: name, foreign_key: :term_id, optional: true
validates :vocabulary, :slug, :position, :level, presence: true
validates :name_translations, translated_attribute_presence: true
validates :slug, uniqueness: { scope: :vocabulary_id }
scope :sorted, -> { order(position: :asc, created_at: :desc) }
scope :with_name, lambda { |name|
where(%(terms.name_translations ->> 'en' ILIKE :name OR
terms.name_translations ->> 'es' ILIKE :name OR
terms.name_translations ->> 'ca' ILIKE :name), name: name.to_s)
}
translates :name, :description
delegate :site, :maximum_level, to: :vocabulary
parent_item_foreign_key :term_id
def attributes_for_slug
[name]
end
def vocabulary_name
vocabulary&.name
end
def destroy
dependent_resources_decorator = TermDependentResourcesDecorator.new(self)
if dependent_resources_decorator.has_dependent_resources?
errors.add(:base, :has_dependent_resources_html, dependencies_list: dependent_resources_decorator.dependencies_list)
return false
end
super
end
def last_descendants
return [self] if level == maximum_level
terms.map(&:last_descendants).flatten
end
def ordered_self_and_descendants
[self, self_and_descendents.reorder(:level).sorted.where(term_id: id).map(&:ordered_self_and_descendants)].flatten
end
def ordered_tree
{ self => self_and_descendents.reorder(:level).sorted.where(term_id: id).inject({}) { |subtree, el| subtree.merge(el.ordered_tree) } }
end
private
def calculate_level
self.level = parent_term.present? ? parent_term.level + 1 : 0
end
def update_children_levels
terms.each do |child|
child.valid? && child.save
end
end
def free_children
terms.each do |child|
child.term_id = nil
child.valid? && child.save
end
end
def set_vocabulary
if parent_term.present?
self.vocabulary_id = parent_term.vocabulary_id
end
end
def enabled_classes_with_vocabularies
vocabulary.site.configuration.modules.map do |module_name|
module_name.constantize.try(:classes_with_vocabularies)
end.flatten.compact
end
def clear_parent_if_itself
if parent_term == self
self.term_id = nil
errors.add(:term_id)
end
end
end
end