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

attributes[R]

The list of Attributes to treat specially during the mapping process

@return [Array<Attribute>] The list of special attributes

model_class[R]

The class to map to

@return [class] The class to map to

models_to_embed[R]

The arrays embedded in this model

@return [Array] An array of embedded models

Public Class Methods

collection_for(model_name) click to toggle source

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
new(model_class, identity_map = IdentityMap) click to toggle source

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

attribute(attribute_name, options = {}) click to toggle source

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
collection_for(model_name = model_class.name) click to toggle source

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
document_to_model(document) click to toggle source

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
edge_attributes() click to toggle source

Returns a list of attributes that have an Edge class configured

@return [Array<Attribute>] A list of attributes which all have an Edge class

# File lib/guacamole/document_model_mapper.rb, line 239
def edge_attributes
  attributes.select(&:map_via_edge?)
end
embeds(model_name) click to toggle source

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
model_to_document(model) click to toggle source

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
responsible_for?(model) click to toggle source

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

handle_embedded_models(model, document) click to toggle source
# 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
identity_map() click to toggle source
# File lib/guacamole/document_model_mapper.rb, line 253
def identity_map
  @identity_map
end