lib/timespan/mongoid.rb in timespan-0.2.8 vs lib/timespan/mongoid.rb in timespan-0.3.1
- old
+ new
@@ -1,35 +1,90 @@
require "timespan"
require "mongoid/fields"
+# http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html
+class Object
+ def meta_def name, &blk
+ (class << self; self; end).instance_eval { define_method name, &blk }
+ end
+end
+
+Mongoid::Fields.option :between do |model, field, options|
+ name = field.name.to_sym
+ model.class_eval do
+ meta_def :"#{name}_between" do |from, to|
+ self.where(:"#{name}.#{TimeSpan.start_field}".gte => from.to_i, :"#{name}.#{TimeSpan.end_field}".lte => to.to_i)
+ end
+ end
+end
+
# Mongoid serialization support for Timespan type.
module Mongoid
module Fields
class Timespan
include Mongoid::Fields::Serializable
+ class << self
+ attr_writer :start_field, :end_field
+
+ def start_field
+ @start_field || :from
+ end
+
+ def end_field
+ @end_field || :to
+ end
+ end
+
def self.instantiate(name, options = {})
super
end
# Deserialize a Timespan given the hash stored by Mongodb
#
# @param [Hash] Timespan as hash
# @return [Timespan] deserialized Timespan
- def deserialize(timespan_hash)
- return if !timespan_hash
- ::Timespan.new(:from => timespan_hash[:from], :to => timespan_hash[:to])
+ def deserialize(hash)
+ return if !hash
+ ::Timespan.new :from => from(hash), :to => to(hash)
end
# Serialize a Timespan or a Hash (with Timespan units) or a Duration in some form to
# a BSON serializable type.
#
# @param [Timespan, Hash, Integer, String] value
# @return [Hash] Timespan in seconds
def serialize(value)
return if value.blank?
- timespan = ::Timespan.new(value)
- {:from => timespan.start_time, :to => timespan.end_time, :duration => timespan.duration.total}
+ timespan = case value
+ when ::Timespan
+ value
+ else
+ ::Timespan.new(value)
+ end
+ {:from => serialize_time(timespan.start_time), :to => serialize_time(timespan.end_time.to_i), :duration => timespan.duration.total }
+ end
+
+ protected
+
+ def from hash
+ from_value = hash['from'] || hash[:from]
+ raise ArgumentError, ":from is nil, #{hash.inspect}" if from_value.nil?
+ deserialize_time from_value
+ end
+
+ def to hash
+ to_value = hash['to'] || hash[:to]
+ raise ArgumentError, ":to is nil, #{hash.inspect}" if to_value.nil?
+ deserialize_time to_value
+ end
+
+ def serialize_time time
+ time.to_i
+ end
+
+ def deserialize_time millisecs
+ Time.at millisecs
end
end
end
end
\ No newline at end of file