Serialization

Not all of our beloved Ruby objects can be serialized and set to the database in our queries. For these cases, Origin provides the means to define custom serializers for Ruby types that need translation to Mongo compatible forms. To get custom serialization for your objects, you need to do 1 of 2 things to "evolve" your objects into Mongo friendly values.

Class Method Evolution

Your first option is to provide a class method named evolve that takes a object on your object's class. A good example of this is Ruby's Date, which MongoDB cannot handle - it only accepts times.

class Date
  def self.evolve(date)
    Time.utc(date.year, date.month, date.day, 0, 0, 0, 0)
  end
end

In the above case, everytime you create a query that has a Date object in it, Origin would convert the date to a UTC time for you. Note that Origin already handles this for you, this is just an example of how it was done.

Key Based Evolution

There may be cases that you want custom serialization based on the name of the field that you are querying on, not the type you passed in. An example of this are named fields in Mongoid - they use a class named Field to handle all of Mongoid's behaviour, but they need to also serialize to the appropriate type when queries are made. Custom named serializers need just to respond to an instance method evolve.

class DateSerializer
  def evolve(date)
    Time.utc(date.year, date.month, date.day, 0, 0, 0, 0)
  end
end

Then when instantiating your queryable, you need to provide it a hash of field name/serializer pairs as its second argument.

class Query
  include Origin::Queryable
end

queryable = Query.new({}, { "date" => DateSerializer.new })

After this, any queries made with the field date in the criteria will use the serializer to convert the value.

queryable.where(date: Date.new) #=> Will convert the date to a time.