module DataSteroid::Properties
Define behaviour to properties of entity.
Public Instance Methods
add_property(name, *args)
click to toggle source
Type might be defined like this:
property :time_field, Time, default: -> { Time.now }
or like this:
property :time_field, type: Time, default: -> { Time.now }
# File lib/data_steroid/properties.rb, line 109 def add_property(name, *args) options = args[-1].is_a?(Hash) ? args[-1].slice(:default, :type) : {} options[:type] = args[0] if args[0] && !(args[0].is_a?(Hash) && args[0].key?(:default)) properties[name.to_s] = options create_accessors(name, options) self end
coerce(value, type)
click to toggle source
# File lib/data_steroid/properties.rb, line 49 def coerce(value, type) if value.nil? || !type value else case when Array == type || Array === type then coerce_array(value, type) when Hash == type || Hash === type then coerce_hash(value, type) when type == Time then coerce_time(value) else coerce_other(value, type) end end end
coerce_array(value, type)
click to toggle source
# File lib/data_steroid/properties.rb, line 62 def coerce_array(value, type) # type: generic Array if type == Array coerce_other(value, type) # type: Array[Something] elsif value.respond_to?(:map) value.map do |element| coerce(element, type[0]) end else raise ArgumentError.new "Invalid coercion: #{value.class} => #{type}" end end
coerce_hash(value, type)
click to toggle source
# File lib/data_steroid/properties.rb, line 76 def coerce_hash(value, type) # type: generic Hash if type == Hash coerce_other(value, type) # type: Hash[Something => Other thing] elsif value.respond_to?(:to_h) k_type, v_type = type.to_a[0] value.to_h.map{ |k,v| [ coerce(k, k_type), coerce(v, v_type) ] }.to_h else raise ArgumentError.new "Invalid coercion: #{value.class} => #{type}" end end
coerce_other(value, type)
click to toggle source
# File lib/data_steroid/properties.rb, line 97 def coerce_other(value, type) coercer[value.class].send("to_#{type.to_s.downcase}", value) end
coerce_time(value)
click to toggle source
# File lib/data_steroid/properties.rb, line 89 def coerce_time(value) case value when Integer then Time.at(value) when String then Time.parse(value) else value end end
coercer()
click to toggle source
# File lib/data_steroid/properties.rb, line 45 def coercer @coercer ||= Coercible::Coercer.new end
create_accessors(name, options)
click to toggle source
www.leighhalliday.com/ruby-metaprogramming-creating-methods
# File lib/data_steroid/properties.rb, line 118 def create_accessors(name, options) define_method(name) do # Define get method instance_variable_get("@#{name}") end define_method("#{name}=") do |value| # Define set method instance_variable_set("@#{name}", coerce(value, options[:type])) end end
properties=(properties)
click to toggle source
# File lib/data_steroid/properties.rb, line 19 def properties=(properties) if properties.is_a? ::Hash properties.each_pair { |key, value| send("#{key}=", value) } else raise Datastore::Errors::DatastoreError.new 'Properties params must be a Hash' end rescue raise Datastore::Errors::DatastoreError.new 'Property invalid' end
properties_names()
click to toggle source
# File lib/data_steroid/properties.rb, line 29 def properties_names properties.keys end
set_default_values()
click to toggle source
# File lib/data_steroid/properties.rb, line 35 def set_default_values properties.each_pair do |name, options| next unless options.key? :default default = options[:default] # Default might be a lambda value = default.respond_to?(:call) ? default.call : default send("#{name}=", value) end end