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
|
# File 'lib/measured/rails/active_record.rb', line 5
def measured(measured_class, *fields)
options = fields.
options = {}.merge(options)
measured_class = measured_class.constantize if measured_class.is_a?(String)
raise Measured::Rails::Error, "Expecting #{ measured_class } to be a subclass of Measured::Measurable" if !measured_class.is_a?(Class) || !measured_class.ancestors.include?(Measured::Measurable)
options[:class] = measured_class
fields.map(&:to_sym).each do |field|
raise Measured::Rails::Error, "The field #{ field } has already been measured" if measured_fields.keys.include?(field)
measured_fields[field] = options
define_method(field) do
value = public_send("#{ field }_value")
unit = public_send("#{ field }_unit")
return nil unless value && unit
instance = instance_variable_get("@measured_#{ field }")
new_instance = begin
measured_class.new(value, unit)
rescue Measured::UnitError
nil
end
if instance && instance == new_instance
instance
else
instance_variable_set("@measured_#{ field }", new_instance)
end
end
define_method("#{ field }=") do |incoming|
if incoming.is_a?(measured_class)
instance_variable_set("@measured_#{ field }", incoming)
value_field_name = "#{ field }_value"
public_send("#{ value_field_name }=", incoming.value.round(self.column_for_attribute(value_field_name).precision))
public_send("#{ field }_unit=", incoming.unit)
else
instance_variable_set("@measured_#{ field }", nil)
public_send("#{ field }_value=", nil)
public_send("#{ field }_unit=", nil)
end
end
define_method("#{ field }_unit=") do |incoming|
incoming = measured_class.conversion.to_unit_name(incoming) if measured_class.valid_unit?(incoming)
write_attribute("#{ field }_unit", incoming)
end
end
end
|