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.