-
Notifications
You must be signed in to change notification settings - Fork 14
Mappers
Mappers are generated by the following structure
Perpetuity.generate_mapper_for MyClass do
# individual mapper configuration goes here
end
This creates a mapper class that defines the way mappers for MyClass
should behave. If you prefer, you can create this class yourself.
class MyClassMapper < Perpetuity::Mapper
map MyClass
end
When doing it this way, the map MyClass
line must be there. This tells the mapper class to register itself with Perpetuity as a mapper for MyClass
.
When persisting object state, we must know which instance variables we will be persisting. In order to declare that, we use the attribute
macro. For example:
Perpetuity.generate_mapper_for Article do
attribute :title
attribute :body
end
Some databases support complex fields. For example, MongoDB allows any JSON objects, so we can embed objects within other objects. To let the mapper know that we would like to store particular attributes that way, we use the embedded
option.
Perpetuity.generate_mapper_for Article do
attribute :comments, embedded: true
end
If we do not declare attributes to be embedded and the database cannot serialize them innately, Perpetuity will store a reference (containing its class and ID) in the currently serialized object. This allows us to use any object that can be serialized by your database or for which we have a mapper.
Sometimes, we would like object IDs to be stored as something other than what the DB thinks they should be. In order to do this, we use the id
macro.
Perpetuity.generate_mapper_for Article do
id { title.gsub(/W+/, '-') }
end
The block is evaluated within the context of the object (in this case, an Article
), which means that we have access to all instance variables and private methods within that particular object, which lets us get at any data we need to form a descriptive ID field. NOTE: Whether this is a good idea or not, I am not sure, but it works for now.
Indexing is important for database performance. If you use a particular attribute often in your queries (whether as criteria for selecting or sorting), you should consider adding an index for it. We can declare indexes with the index
macro:
Perpetuity.generate_mapper_for Article do
attribute :title
index :title
end
This does not immediately enforce an index on the database, though, since that can cause downtime for your app. It is best to choose to run things like that in a rake task. We can enforce that index with the reindex!
method:
Perpetuity[Article].reindex!
This will ensure that all of your indexes are performed on the database collection.
Accessing mappers after they have been generated is done through the use of the subscript operator on the Perpetuity
namespace. For example, if you generate a mapper class for the Article
class, you can reach an instance of it by calling Perpetuity[Article]
.
Perpetuity[Article].insert article
In a Rails controller, a good practice is to memoize this so your code is not littered with Perpetuity[MyClass]
:
class ArticlesController < ApplicationController
def index
@articles = mapper.all
end
private
def mapper
@mapper ||= Perpetuity[Article]
end
end