class Guacamole::DocumentModelMapper
This is the default mapper class to map between Ashikawa::Core::Document and Guacamole::Model
instances.
If you want to build your own mapper, you have to build at least the ‘document_to_model` and `model_to_document` methods.
@note If you plan to bring your own ‘DocumentModelMapper` please consider using an {Guacamole::IdentityMap}.
Attributes
The list of Attributes to treat specially during the mapping process
@return [Array<Attribute>] The list of special attributes
The class to map to
@return [class] The class to map to
The arrays embedded in this model
@return [Array] An array of embedded models
Public Class Methods
construct the {collection} class for a given model name.
@example
collection_class = collection_for(:user) collection_class == userscollection # would be true
@note This is an class level alias for {DocumentModelMapper#collection_for} @param [symbol, string] model_name the name of the model @return [class] the {collection} class for the given model name
# File lib/guacamole/document_model_mapper.rb, line 125 def collection_for(model_name) "#{model_name.to_s.classify.pluralize}Collection".constantize end
Create a new instance of the mapper
You have to provide the model class you want to map to. The Document class is always Ashikawa::Core::Document
@param [Class] model_class
# File lib/guacamole/document_model_mapper.rb, line 108 def initialize(model_class, identity_map = IdentityMap) @model_class = model_class @identity_map = identity_map @models_to_embed = [] @attributes = [] end
Public Instance Methods
Mark an attribute of the model to be specially treated during mapping
@param [Symbol] attribute_name The name of the model attribute @param [Hash] options Additional options to configure the mapping process @option options [Edge] :via The Edge
class this attribute relates to @example Define a relation via an Edge
in a Graph
class Authorship include Guacamole::Edge from :users to :posts end class BlogpostsCollection include Guacamole::Collection map do attribute :author, via: Authorship end end
# File lib/guacamole/document_model_mapper.rb, line 232 def attribute(attribute_name, options = {}) @attributes << Attribute.new(attribute_name, options) end
construct the {collection} class for a given model name.
@example
collection_class = collection_for(:user) collection_class == userscollection # would be true
@todo As of now this is some kind of placeholder method. As soon as we implement
the configuration of the mapping (#12) this will change. Still the {DocumentModelMapper} seems to be a good place for this functionality.
@param [symbol, string] model_name the name of the model @return [class] the {collection} class for the given model name
# File lib/guacamole/document_model_mapper.rb, line 141 def collection_for(model_name = model_class.name) self.class.collection_for model_name end
Map a document to a model
Sets the revision, key and all attributes on the model
@param [Ashikawa::Core::Document] document @return [Model] the resulting model with the given Model
class
# File lib/guacamole/document_model_mapper.rb, line 151 def document_to_model(document) identity_map.retrieve_or_store model_class, document.key do model = model_class.new(document.to_h) model.key = document.key model.rev = document.revision handle_related_documents(model) model end end
Declare a model to be embedded
With embeds you can specify that the document in the collection embeds a document that should be mapped to a certain model. Your model has to specify an attribute with the type Array (of this model).
@param [Symbol] model_name Pluralized name of the model class to embed @example A blogpost with embedded comments
class BlogpostsCollection include Guacamole::Collection map do embeds :comments end end class Blogpost include Guacamole::Model attribute :comments, Array[Comment] end class Comment include Guacamole::Model end blogpost = BlogpostsCollection.find('12313121') p blogpost.comments #=> An Array of Comments
# File lib/guacamole/document_model_mapper.rb, line 208 def embeds(model_name) @models_to_embed << model_name end
Map a model to a document
This will include all embedded models
@param [Model] model @return [Ashikawa::Core::Document] the resulting document
# File lib/guacamole/document_model_mapper.rb, line 170 def model_to_document(model) document = model.attributes.dup.except(:key, :rev) handle_embedded_models(model, document) handle_related_models(document) document end
Is this Mapper instance responsible for mapping the given model
@param [Model] model The model to check against @return [Boolean] True if the given model is an instance of model_class
. False if not.
# File lib/guacamole/document_model_mapper.rb, line 247 def responsible_for?(model) model.instance_of?(model_class) end
Private Instance Methods
# File lib/guacamole/document_model_mapper.rb, line 257 def handle_embedded_models(model, document) models_to_embed.each do |attribute_name| document[attribute_name] = model.send(attribute_name).map do |embedded_model| embedded_model.attributes.except(:key, :rev) end end end
# File lib/guacamole/document_model_mapper.rb, line 253 def identity_map @identity_map end