module Frenchy::Model::ClassMethods
Public Instance Methods
defaults()
click to toggle source
# File lib/frenchy/model.rb, line 58 def defaults; @defaults; end
defaults=(value)
click to toggle source
# File lib/frenchy/model.rb, line 60 def defaults=(value); @defaults = value; end
fields()
click to toggle source
Class accessors
# File lib/frenchy/model.rb, line 57 def fields; @fields; end
fields=(value)
click to toggle source
# File lib/frenchy/model.rb, line 59 def fields=(value); @fields = value; end
Protected Instance Methods
embed(name, options={}, &block)
click to toggle source
Macro to create a subtype and associated field
# File lib/frenchy/model.rb, line 90 def embed(name, options={}, &block) type(name, &block) field(name, options.merge({type: name})) end
enum(name, &block)
click to toggle source
Macro to add an enum type
# File lib/frenchy/model.rb, line 81 def enum(name, &block) klass = Class.new(self) do include Frenchy::Enum end const_set(name.to_s.camelize, klass) klass.class_eval(&block) end
field(name, options={})
click to toggle source
Macro to add a field
# File lib/frenchy/model.rb, line 96 def field(name, options={}) name = name.to_s options.stringify_keys! if options["enum"] options["type"] = "enum" options["class_name"] ||= options["enum"].to_s.camelize end type = (options["type"] || "string").to_s aliases = (options["aliases"] || []) aliases.each do |a| define_method("#{a}") do send(name) end end case type when "string" # Convert value to a String. define_method("#{name}=") do |v| set(name, String(v)) end when "integer" # Convert value to an Integer. define_method("#{name}=") do |v| set(name, Integer(v)) end when "float" # Convert value to a Float. define_method("#{name}=") do |v| set(name, Float(v)) end when "bool" # Accept truthy values as true. define_method("#{name}=") do |v| set(name, ["true", "1", 1, true].include?(v)) end # Alias a predicate method. define_method("#{name}?") do send(name) end when "time" # 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?(Integer) 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 when "array" # Arrays always have a default of [] options["default"] ||= [] # Convert value to an Array. define_method("#{name}=") do |v| set(name, Array(v)) end when "hash" # Hashes always have a default of {} options["default"] ||= {} # Convert value to a Hash define_method("#{name}=") do |v| set(name, Hash[v]) end when "enum" # Resolve the class name klass = const_get(options["class_name"]) # Convert value to enum class define_method("#{name}=") do |v| set(name, klass.find(v.to_i)) 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 = 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 # Convert value using the constantized class. Fields with many values are mapped to a # Frenchy::Collection containing mapped values. define_method("#{name}=") do |v| if options["many"] set(name, Frenchy::Collection.new(Array(v).map {|vv| klass.new(vv)})) else if v.is_a?(Hash) set(name, klass.new(v)) else set(name, v) end end end end # Store a reference to the field self.fields[name] = options # Store a default value if present if options["default"] self.defaults[name] = options["default"] end # Create an accessor for the field attr_reader name end
key(name)
click to toggle source
Macro to add primary key
# File lib/frenchy/model.rb, line 65 def key(name) define_method(:to_param) do send(name).to_s end end
type(name, &block)
click to toggle source
Macro to create a subtype
# File lib/frenchy/model.rb, line 72 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