I think you want to at least consider using Ruby's Rational class to help. Here's a pure Ruby example:
class Measurable
attr_accessor :id, :unit_id, :measurable_type_id, :reliability_id, :created_at, :updated_at
attr_reader :value
# belongs_to :measurable_type
def initialize(input)
self.value = input
end
def value=(input)
case input
when String
# Has more than one value
if (parts = input.split(" ")).size > 1
result = parts.reduce(0) {|whole,part| whole + Rational(part) }
else
result = input.to_f
end
when Numeric
result = input
else
result = input.to_f
end
@value = result
end
def to_s
case self.value
when Rational
whole = self.value.floor
"%d %s"%[whole, (self.value - whole).to_s]
else
self.value.to_s
end
end
end
irb2.2.4> puts Measurable.new("31 1/8")
31 1/8
#2.2.4 => nil
irb2.2.4> puts Measurable.new("31.125")
31.125
#2.2.4 => nil
irb2.2.4> puts Measurable.new(31.125)
31.125
#2.2.4 => nil
There's also a to_r method to convert types to a Rational if your "measurable_type" wanted to convert strictly to a Rational form.
-Rob