lib/frenchy/model.rb in frenchy-0.3.0 vs lib/frenchy/model.rb in frenchy-0.4.0

- old
+ new

@@ -5,11 +5,10 @@ base.class_eval do self.fields = {} self.defaults = {} end - end # Create a new instance of this model with the given attributes def initialize(attrs={}) attrs.stringify_keys! @@ -52,11 +51,10 @@ def set(name, value) instance_variable_set("@#{name}", value) end module ClassMethods - # Class accessors def fields; @fields; end def defaults; @defaults; end def fields=(value); @fields = value; end def defaults=(value); @defaults = value; end @@ -68,10 +66,25 @@ define_method(:to_param) do send(name).to_s end end + # Macro to create a subtype + def type(name, &block) + klass = Class.new(self) do + include Frenchy::Model + end + const_set(name.to_s.camelize, klass) + klass.class_eval(&block) + end + + # Macro to create a subtype and associated field + def embed(name, options={}, &block) + type(name, &block) + field(name, options.merge({type: name})) + end + # Macro to add a field def field(name, options={}) name = name.to_s options.stringify_keys! @@ -118,10 +131,14 @@ # Convert value to a Time or DateTime. Numbers are treated as unix timestamps, # other values are parsed with DateTime.parse. define_method("#{name}=") do |v| if v.is_a?(Fixnum) set(name, Time.at(v).to_datetime) + elsif v.is_a?(DateTime) + set(name, v) + elsif v.is_a?(Time) + set(name, v.to_datetime) else set(name, DateTime.parse(v)) end end @@ -144,10 +161,10 @@ end else # Unknown types have their type constantized and initialized with the value. This # allows us to support things like other Frenchy::Model classes, ActiveRecord models, etc. - klass = (options["class_name"] || type.camelize).constantize + klass = const_get(options["class_name"] || type.camelize) # Fields with many values have a default of [] (unless previously set above) if options["many"] options["default"] ||= [] end