lib/volt/models/field_helpers.rb in volt-0.9.4 vs lib/volt/models/field_helpers.rb in volt-0.9.5.pre1

- old
+ new

@@ -1,19 +1,51 @@ # Provides a method to setup a field on a model. module FieldHelpers class InvalidFieldClass < RuntimeError; end + NUMERIC_CAST = lambda do |convert_method, val| + begin + orig = val + val = send(convert_method, val) + + if RUBY_PLATFORM == 'opal' + # Opal has a bug in 0.7.2 that gives us back NaN without an + # error sometimes. + val = orig if val.nan? + end + rescue TypeError, ArgumentError => e + # ignore, unmatched types will be caught below. + val = orig + end + + return val + end + + FIELD_CASTS = { + String => :to_s.to_proc, + Fixnum => lambda {|val| NUMERIC_CAST[:Integer, val] }, + Numeric => lambda {|val| NUMERIC_CAST[:Float, val] }, + Float => lambda {|val| NUMERIC_CAST[:Float, val] }, + Time => nil, + TrueClass => nil, + FalseClass => nil + } + VALID_FIELD_CLASSES = FIELD_CASTS.keys + + module ClassMethods # field lets you declare your fields instead of using the underscore syntax. # An optional class restriction can be passed in. - def field(name, klass = nil) - if klass && ![String, Numeric].include?(klass) - fail FieldHelpers::InvalidFieldClass, 'valid field types is currently limited to String or Numeric' + def field(name, klass = nil, auto_cast = true) + if klass && !VALID_FIELD_CLASSES.include?(klass) + klass_names = VALID_FIELD_CLASSES.map(&:to_s).join(', ') + msg = "valid field types is currently limited to #{klass_names}" + fail FieldHelpers::InvalidFieldClass, msg end if klass - # Add type validation, execpt for String, since anything can be a string. + # Add type validation, execpt for String, since anything can be a string. unless klass == String validate name, type: klass end end @@ -23,26 +55,11 @@ define_method(:"#{name}=") do |val| # Check if the value assigned matches the class restriction if klass # Cast to the right type - if klass == String - val = val.to_s - elsif klass == Numeric - begin - orig = val - unless val.is_a?(Numeric) - val = Float(val) - end - - if RUBY_PLATFORM == 'opal' - # Opal has a bug in 0.7.2 that gives us back NaN without an - # error sometimes. - val = orig if val.nan? - end - rescue TypeError, ArgumentError => e - # ignore, unmatched types will be caught below. - end + if (func = FIELD_CASTS[klass]) + val = func[val] end end set(name, val) end