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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
|
# File 'lib/aux_codes.rb', line 12
def self.included base
base.class_eval do
include DataMapper::Resource
property :id, DataMapper::Types::Serial
property :aux_code_id, Integer, :default => 0
property :name, String, :required => true, :unique => :aux_code_id
property :meta, DataMapper::Types::Text
belongs_to :aux_code
has n, :aux_codes
def self.name
'AuxCode'
end
alias code aux_code
alias category aux_code
alias codes aux_codes
def self.find_all_by_aux_code_id aux_code_id
all :aux_code_id => aux_code_id
end
def self.find_by_name_and_aux_code_id name, aux_code_id
first :name => name, :aux_code_id => aux_code_id
end
def self.find_or_create_by_name name
first(:name => name) || create(:name => name)
end
def self.find_by_name name
first :name => name
end
def self.find_all_by_name name
all :name => name
end
def code_names
codes.map &:name
end
def is_a_category?
aux_code_id == 0
end
def class_name
name.gsub(/[^[:alpha:]]/,'_').titleize.gsub(' ','').singularize
end
def to_s
name
end
def [] attribute_or_code_name
if attributes.include?attribute_or_code_name
attributes[attribute_or_code_name]
else
found = codes.select {|c| c.name.to_s =~ /#{attribute_or_code_name}/ }
if found.empty? found = codes.select {|c| c.name.downcase.gsub('_',' ').to_s =~
/#{attribute_or_code_name.to_s.downcase.gsub('_',' ')}/ }
end
found.first if found
end
end
def deserialized_meta_hash
require 'yaml'
self.meta ||= ""
YAML::load(self.meta) || { }
end
def get_meta_attribute meta_attribute
deserialized_meta_hash[meta_attribute.to_s]
end
def set_meta_attribute meta_attribute, value
require 'yaml'
meta_hash = deserialized_meta_hash
meta_hash[meta_attribute.to_s] = value
self.meta = meta_hash.to_yaml
end
def method_missing_with_indifferent_hash_style_values name, *args, &block
method_missing_without_indifferent_hash_style_values name, *args, &block
rescue NoMethodError => ex
begin
if name.to_s[/=$/]
self.set_meta_attribute(name.to_s.sub(/=$/,''), args.first) save
else
code = self[name]
code = self.get_meta_attribute(name) unless code
raise ex unless code
return code
end
rescue
raise ex
end
end
alias_method_chain :method_missing, :indifferent_hash_style_values
class << self
def categories
AuxCode.find_all_by_aux_code_id(0)
end
def category_names
AuxCode.categories.map &:name
end
def category category_object_or_id_or_name
obj = category_object_or_id_or_name
return obj if obj.is_a?(AuxCode)
return AuxCode.get(obj) if obj.is_a?(Fixnum)
if obj.is_a?(String) || obj.is_a?(Symbol)
obj = obj.to_s
found = AuxCode.find_by_name_and_aux_code_id(obj, 0)
if found.nil?
found = AuxCode.first :name.like => obj.gsub('_', ' '), :aux_code_id => 0
end
return found
end
raise "I don't know how to find an AuxCode of type #{ obj.class }"
end
alias [] category
def category_codes category_object_or_id_or_name
category( category_object_or_id_or_name ).codes
end
alias category_values category_codes
def category_code_names category_object_or_id_or_name
category( category_object_or_id_or_name ).code_names
end
def create_classes!
AuxCode.categories.each do |category|
Object.const_set category.class_name, category.aux_code_class unless Object.const_defined?(category.class_name)
end
end
def method_missing_with_indifferent_hash_style_values name, *args, &block
begin
method_missing_without_indifferent_hash_style_values name, *args, &block
rescue NoMethodError => ex
begin
self[name]
rescue
raise ex
end
end
end
alias_method_chain :method_missing, :indifferent_hash_style_values
def load_yaml yaml_string
require 'yaml'
self.load_from YAML::load(yaml_string)
end
def load_file serialized_yaml_file_path
load_yaml File.read(serialized_yaml_file_path)
end
def init create_root_code!
aux_codes_yml = File.join 'config', 'aux_codes.yml'
if File.file? aux_codes_yml
load_file aux_codes_yml
create_classes!
end
end
def create_root_code!
AuxCode.create :id => 0, :name => 'Aux Code Categories' unless AuxCode.get(0)
end
def load_from hash
return unless hash.is_a?(Hash)
hash.each do |category_name, codes|
category = AuxCode.find_or_create_by_name( category_name.to_s ).aux_code_class
codes.each do |name, values|
if values.nil? or values.empty?
if name.is_a? String or name.is_a? Symbol category.create :name => name.to_s unless category.code_names.include?(name.to_s)
elsif name.is_a? Hash category.create name
else
raise "not sure how to create code in category #{ category.name } with: #{ name.inspect }"
end
else
if values.is_a? Hash and (name.is_a? String or name.is_a? Symbol) code = category[ name.to_s ]
if code
values.each do |attribute, new_value|
code.send "#{attribute}=", new_value end
else
code = category.create values.merge({ :name => name.to_s })
end
else
raise "not sure how to create code in category #{ category.name } with: #{ name.inspect }, #{ values.inspect }"
end
end
end
end
end
end
end
end
|