Class: Onoma::Item
- Inherits:
-
Object
show all
- Defined in:
- lib/onoma/item.rb
Overview
An item of a nomenclature is the core data.
Instance Attribute Summary collapse
Instance Method Summary
collapse
Constructor Details
#initialize(nomenclature, name, options = {}) ⇒ Item
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
# File 'lib/onoma/item.rb', line 9
def initialize(nomenclature, name, options = {})
@nomenclature = nomenclature
@name = name.to_s
@left, @right = @nomenclature.new_boundaries
@depth = 0
@parent = nil
@parent_name = nil
parent = options.delete(:parent)
if parent.is_a?(Symbol) || parent.is_a?(String)
@parent_name = parent.to_s
else
self.parent = parent
end
@attributes = ActiveSupport::HashWithIndifferentAccess.new
@children = Set.new
options.each do |k, v|
set(k, v)
end
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args) ⇒ Object
Returns property descriptor
292
293
294
295
|
# File 'lib/onoma/item.rb', line 292
def method_missing(method_name, *args)
return property(method_name) if has_property?(method_name)
super
end
|
Instance Attribute Details
#aliases ⇒ Object
Returns the value of attribute aliases.
4
5
6
|
# File 'lib/onoma/item.rb', line 4
def aliases
@aliases
end
|
#attributes ⇒ Object
Also known as:
properties
Returns the value of attribute attributes.
5
6
7
|
# File 'lib/onoma/item.rb', line 5
def attributes
@attributes
end
|
#depth ⇒ Object
Returns the value of attribute depth.
4
5
6
|
# File 'lib/onoma/item.rb', line 4
def depth
@depth
end
|
#left ⇒ Object
Returns the value of attribute left.
4
5
6
|
# File 'lib/onoma/item.rb', line 4
def left
@left
end
|
#name ⇒ Object
Returns the value of attribute name.
5
6
7
|
# File 'lib/onoma/item.rb', line 5
def name
@name
end
|
#nomenclature ⇒ Object
Returns the value of attribute nomenclature.
4
5
6
|
# File 'lib/onoma/item.rb', line 4
def nomenclature
@nomenclature
end
|
#parent_name ⇒ Object
Returns the value of attribute parent_name.
4
5
6
|
# File 'lib/onoma/item.rb', line 4
def parent_name
@parent_name
end
|
#right ⇒ Object
Returns the value of attribute right.
4
5
6
|
# File 'lib/onoma/item.rb', line 4
def right
@right
end
|
Instance Method Details
#<(other) ⇒ Object
201
202
203
204
|
# File 'lib/onoma/item.rb', line 201
def <(other)
other = item_for_comparison(other)
(other.left < @left && @right < other.right)
end
|
#<=(other) ⇒ Object
211
212
213
214
|
# File 'lib/onoma/item.rb', line 211
def <=(other)
other = item_for_comparison(other)
(other.left <= @left && @right <= other.right)
end
|
#<=>(other) ⇒ Object
196
197
198
199
|
# File 'lib/onoma/item.rb', line 196
def <=>(other)
other = item_for_comparison(other)
nomenclature.name <=> other.nomenclature.name && name <=> other.name
end
|
#==(other) ⇒ Object
191
192
193
194
|
# File 'lib/onoma/item.rb', line 191
def ==(other)
other = item_for_comparison(other)
nomenclature == other.nomenclature && name == other.name
end
|
#>(other) ⇒ Object
206
207
208
209
|
# File 'lib/onoma/item.rb', line 206
def >(other)
other = item_for_comparison(other)
(@left < other.left && other.right < @right)
end
|
#>=(other) ⇒ Object
216
217
218
219
|
# File 'lib/onoma/item.rb', line 216
def >=(other)
other = item_for_comparison(other)
(@left <= other.left && other.right <= @right)
end
|
#add_child(item) ⇒ Object
59
60
61
|
# File 'lib/onoma/item.rb', line 59
def add_child(item)
@children << item
end
|
#children(options = {}) ⇒ Object
Returns children recursively by default
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
# File 'lib/onoma/item.rb', line 108
def children(options = {})
if options[:index].is_a?(FalseClass)
if options[:recursively].is_a?(FalseClass)
@children.to_a
else
children(index: false, recursive: false).each_with_object([]) do |item, list|
list << item
list += item.children(index: false, recursive: true)
list
end
end
else
if options[:recursively].is_a?(FalseClass)
nomenclature.list.select do |item|
@left < item.left && item.right < @right && item.depth == @depth + 1
end
else
nomenclature.list.select do |item|
@left < item.left && item.right < @right
end
end
end
end
|
#degree_of_kinship_with(other) ⇒ Object
89
90
91
92
93
94
95
96
97
98
99
100
|
# File 'lib/onoma/item.rb', line 89
def degree_of_kinship_with(other)
other_item = item_for_comparison(other)
a = self_and_parents.reverse
b = other_item.self_and_parents.reverse
return nil if a.first != b.first
common_lineage = 0
a.size.times do |index|
break if a[index].nil? || b[index].nil? || a[index] != b[index]
common_lineage += 1
end
a.size + b.size - 2 * common_lineage
end
|
#delete_child(item) ⇒ Object
63
64
65
|
# File 'lib/onoma/item.rb', line 63
def delete_child(item)
@children.delete(item)
end
|
#find_parent ⇒ Object
85
86
87
|
# File 'lib/onoma/item.rb', line 85
def find_parent
@nomenclature.find(@parent_name)
end
|
#has_property?(name) ⇒ Boolean
Checks if item has property with given name
287
288
289
|
# File 'lib/onoma/item.rb', line 287
def has_property?(name)
!@nomenclature.properties[name].nil?
end
|
#human_name(options = {}) ⇒ Object
Also known as:
humanize, localize
Return human name of item
180
181
182
|
# File 'lib/onoma/item.rb', line 180
def human_name(options = {})
I18n.translate("nomenclatures.#{nomenclature.name}.items.#{name}", options.merge(default: ["items.#{name}".to_sym, "enumerize.#{nomenclature.name}.#{name}".to_sym, "labels.#{name}".to_sym, name.humanize]))
end
|
#human_notion_name(notion_name, options = {}) ⇒ Object
187
188
189
|
# File 'lib/onoma/item.rb', line 187
def human_notion_name(notion_name, options = {})
"nomenclatures.#{nomenclature.name}.notions.#{notion_name}.#{name}".t(options.merge(default: ["labels.#{name}".to_sym]))
end
|
#include?(other) ⇒ Boolean
Returns true if the given item name match the current item or its children
175
176
177
|
# File 'lib/onoma/item.rb', line 175
def include?(other)
self >= other
end
|
#inspect ⇒ Object
221
222
223
|
# File 'lib/onoma/item.rb', line 221
def inspect
"#{@nomenclature.name}-#{@name}(#{@left}-#{@right})"
end
|
#original_nomenclature_name ⇒ Object
102
103
104
105
|
# File 'lib/onoma/item.rb', line 102
def original_nomenclature_name
return parent.name.to_sym unless root?
nil
end
|
#parent ⇒ Object
Also known as:
fetch_parent
77
78
79
80
81
82
|
# File 'lib/onoma/item.rb', line 77
def parent
return @parent if @parent
@parent = find_parent
@parent.add_child(self) if @parent
@parent
end
|
#parent=(item) ⇒ Object
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
|
# File 'lib/onoma/item.rb', line 33
def parent=(item)
old_parent_name = @parent_name
old_parent = @parent
if item.nil?
@parent = nil
@parent_name = nil
else
if item.is_a?(Symbol) || item.is_a?(String)
item = nomenclature.find!(item.to_s)
end
if item.nomenclature != nomenclature
raise 'Item must come from same nomenclature'
end
if item.parents.any? { |p| self == p } || self == item
raise 'Circular dependency. Item can be parent of itself.'
end
@parent = item
@parent_name = @parent.name.to_s
end
if old_parent_name != @parent_name
old_parent.delete_child(self) if old_parent
@parent.add_child(self) if @parent
@nomenclature.rebuild_tree!
end
end
|
#parent? ⇒ Boolean
73
74
75
|
# File 'lib/onoma/item.rb', line 73
def parent?
parent.present?
end
|
#parents ⇒ Object
Returns direct parents from the closest to the farthest
138
139
140
|
# File 'lib/onoma/item.rb', line 138
def parents
@parents ||= (parent.nil? ? [] : [parent] + parent.parents)
end
|
#property(name) ⇒ Object
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
|
# File 'lib/onoma/item.rb', line 251
def property(name)
return @name.to_sym if name == :name
property = @nomenclature.properties[name]
value = @attributes[name]
if property
if value.nil? && property.fallbacks
property.fallbacks.each do |fallback|
value ||= @attributes[fallback]
break if value
end
end
value ||= cast_property(name, property.default) if property.default
end
value
end
|
#rebuild_tree(left = 0, depth = 0) ⇒ Object
Computes left/right value for nested set Returns right index
164
165
166
167
168
169
170
171
172
|
# File 'lib/onoma/item.rb', line 164
def rebuild_tree(left = 0, depth = 0)
@depth = depth
@left = left
@right = @left + 1
children(index: false, recursively: false).each do |child|
@right = child.rebuild_tree(@right, @depth + 1) + 1
end
@right
end
|
#rebuild_tree! ⇒ Object
Computes left/right value for nested set Returns right index
158
159
160
|
# File 'lib/onoma/item.rb', line 158
def rebuild_tree!
@nomenclature.forest_right = rebuild_tree(@nomenclature.forest_right + 1)
end
|
#rise(&block) ⇒ Object
150
151
152
153
154
|
# File 'lib/onoma/item.rb', line 150
def rise(&block)
result = yield(self)
return result if result
parent ? parent.rise(&block) : nil
end
|
#root ⇒ Object
133
134
135
|
# File 'lib/onoma/item.rb', line 133
def root
parent? ? parent.root : self
end
|
#root? ⇒ Boolean
29
30
31
|
# File 'lib/onoma/item.rb', line 29
def root?
!parent
end
|
#selection(name) ⇒ Object
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
|
# File 'lib/onoma/item.rb', line 267
def selection(name)
property = @nomenclature.properties[name]
if property.list?
return property(name).collect do |i|
["nomenclatures.#{@nomenclature.name}.item_lists.#{self.name}.#{name}.#{i}".t, i]
end
elsif property.nomenclature?
target_nomenclature = Onoma.find(property(name).to_sym)
unless target_nomenclature
raise "Cannot find nomenclature: for #{property(name).inspect}"
end
return target_nomenclature.list.collect do |i|
[i.human_name, i.name]
end
else
raise StandardError, 'Cannot call selection for a non-list property'
end
end
|
#self_and_children(options = {}) ⇒ Object
142
143
144
|
# File 'lib/onoma/item.rb', line 142
def self_and_children(options = {})
[self] + children(options)
end
|
#self_and_parents ⇒ Object
146
147
148
|
# File 'lib/onoma/item.rb', line 146
def self_and_parents
[self] + parents
end
|
#set(name, value) ⇒ Object
297
298
299
300
301
302
303
304
305
306
307
308
|
# File 'lib/onoma/item.rb', line 297
def set(name, value)
raise "Invalid property: #{name.inspect}" if i[name parent].include?(name.to_sym)
if value.nil?
@attributes.delete(name)
else
@attributes[name] = value
end
end
|
#to_xml_attrs ⇒ Object
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
|
# File 'lib/onoma/item.rb', line 233
def to_xml_attrs
attrs = {}
attrs[:name] = name
attrs[:parent] = @parent_name if parent?
properties.each do |pname, pvalue|
if p = nomenclature.properties[pname.to_s]
if p.type == :decimal
pvalue = pvalue.to_s.to_f
elsif p.list?
pvalue = pvalue.join(', ')
end
end
attrs[pname] = pvalue.to_s
end
attrs
end
|
#tree(depth = 0) ⇒ Object
225
226
227
228
229
230
231
|
# File 'lib/onoma/item.rb', line 225
def tree(depth = 0)
text = "#{left.to_s.rjust(4)}-#{right.to_s.ljust(4)} #{' ' * depth}#{@name}:\n"
text << children(index: false, recursively: false).collect do |c|
c.tree(depth + 1)
end.join("\n")
text
end
|