module Guacamole::Collection::ClassMethods

The class methods added to the class via the mixin

@!method model_to_document(model)

Convert a model to a document to save it to the database

You can use this method for your hand made storage or update methods.
Most of the time it makes more sense to call save or update though,
they do the conversion and handle the communication with the database

@param [Model] model The model to be converted
@return [Ashikawa::Core::Document] The converted document

Attributes

connection[RW]
database[RW]
graph[RW]
mapper[RW]

Public Instance Methods

all() click to toggle source

Get all Models stored in the collection

The result can be limited (and should be for most datasets) This can be done one the returned Query object. All methods of the Enumerable module and ‘.to_a` will lead to the execution of the query.

@return [Query] @example Get all podcasts

podcasts = PodcastsCollection.all.to_a

@example Get the first 50 podcasts

podcasts = PodcastsCollection.all.limit(50).to_a
# File lib/guacamole/collection.rb, line 280
def all
  Query.new(connection.query, mapper)
end
by_aql(aql_fragment, bind_parameters = {}, options = {}) click to toggle source

Find models with simple AQL queries

Since Simple Queries are quite limited in their possibilities you will need to use AQL for more advanced data retrieval. Currently there is only a very basic support for AQL. Nevertheless it will allow to use any arbitrary query you want.

@param [String] aql_fragment An AQL string that will will be put between the

`FOR x IN coll` and the `RETURN x` part.

@param [Hash<Symbol, String>] bind_parameters The parameters to be passed into the query @param [Hash] options Additional options for the query execution @option options [String] :return_as (‘RETURN #{model_name}’) A custom ‘RETURN` statement @option options [Boolean] :mapping (true) Should the mapping be performed? @return [Query] @note Please use always bind parameters since they provide at least some form

of protection from AQL injection.

@see docs.arangodb.com/Aql/README.html AQL Documentation

# File lib/guacamole/collection.rb, line 261
def by_aql(aql_fragment, bind_parameters = {}, options = {})
  query                 = AqlQuery.new(self, mapper, options)
  query.aql_fragment    = aql_fragment
  query.bind_parameters = bind_parameters
  query
end
by_example(example) click to toggle source

Find models by the provided attributes

Search for models in the collection where the attributes are equal to those that you provided. This returns a Query object, where you can provide additional information like limiting the results. See the documentation of Query or the examples for more information. All methods of the Enumerable module and ‘.to_a` will lead to the execution of the query.

@param [Hash] example The attributes and their values @return [Query] @example Get all podcasts with the title ‘Best Podcast’

podcasts = PodcastsCollection.by_example(title: 'Best Podcast').to_a

@example Get the second batch of podcasts for batches of 10 with the title ‘Best Podcast’

podcasts = PodcastsCollection.by_example(title: 'Best Podcast').skip(10).limit(10).to_a

@example Iterate over all podcasts with the title ‘Best Podcasts’

PodcastsCollection.by_example(title: 'Best Podcast').each do |podcast|
  p podcast
end
# File lib/guacamole/collection.rb, line 239
def by_example(example)
  query = all
  query.example = example
  query
end
by_key(key) click to toggle source

Find a model by its key

The key is the unique identifier of a document within a collection, this concept is similar to the concept of IDs in most databases.

@param [String] key @return [Model] The model with the given key @example Find a podcast by its key

podcast = PodcastsCollection.by_key('27214247')
# File lib/guacamole/collection.rb, line 112
def by_key(key)
  raise Ashikawa::Core::DocumentNotFoundException unless key

  mapper.document_to_model fetch_document(key)
end
callbacks(model) click to toggle source

Gets the callback class for the given model class

@api private @param [Model] model The model to look up callbacks for @return [Callbacks] An instance of the registered callback class

# File lib/guacamole/collection.rb, line 332
def callbacks(model)
  Callbacks.callbacks_for(model)
end
collection_name() click to toggle source

The name of the collection in ArangoDB

Use this method in your hand crafted AQL queries, for debugging etc.

@return [String] The name

# File lib/guacamole/collection.rb, line 92
def collection_name
  @collection_name ||= name.gsub(/Collection\z/, '').underscore
end
consistently_get_document_and_model(model_or_key) click to toggle source

Gets the document and model instance for either a given model or a key.

@api private @param [String, Model] model_or_key The key of the model or a model @return [Array<Ashikawa::Core::Document, Model>] Both the document and model for the given input

# File lib/guacamole/collection.rb, line 189
def consistently_get_document_and_model(model_or_key)
  if model_or_key.respond_to?(:key)
    [fetch_document(model_or_key.key), model_or_key]
  else
    [document = fetch_document(model_or_key), mapper.document_to_model(document)]
  end
end
create(model) click to toggle source

Persist a model in the collection

The model will be saved in the collection. Timestamps, revision and key will be set on the model.

@param [Model] model The model to be saved @return [Model] The provided model @example Save a podcast to the database

podcast = Podcast.new(title: 'Best Show', guest: 'Dirk Breuer')
PodcastsCollection.save(podcast)
podcast.key #=> '27214247'
# File lib/guacamole/collection.rb, line 154
def create(model)
  return false unless model.valid?

  callbacks(model).run_callbacks :save, :create do
    create_document_from(model)
  end
  model
end
create_document_from(model) click to toggle source

Create a document from a model

@api private @todo Currently we only save the associated models if those never have been

persisted. In future versions we should add something like `:autosave`
to always save associated models.
# File lib/guacamole/collection.rb, line 302
def create_document_from(model)
  result = with_transaction(model)

  model.key = result[model.object_id.to_s]['_key']
  model.rev = result[model.object_id.to_s]['_rev']

  model
end
delete(model_or_key) click to toggle source

Delete a model from the database

If you provide a key, we will fetch the model first to run the ‘:delete` callbacks for that model.

@param [String, Model] model_or_key The key of the model or a model @return [String] The key @example Delete a podcast by key

PodcastsCollection.delete(podcast.key)

@example Delete a podcast by model

PodcastsCollection.delete(podcast)
# File lib/guacamole/collection.rb, line 174
def delete(model_or_key)
  document, model = consistently_get_document_and_model(model_or_key)

  callbacks(model).run_callbacks :delete do
    document.delete
  end

  model.key
end
map(&block) click to toggle source

Specify details on the mapping

The method is called with a block where you can specify details about the way that the data from the database is mapped to models.

See ‘DocumentModelMapper` for details on how to configure the mapper.

# File lib/guacamole/collection.rb, line 292
def map(&block)
  mapper.instance_eval(&block)
end
model_class() click to toggle source

The class of the resulting models

@return [Class] The model class

# File lib/guacamole/collection.rb, line 99
def model_class
  @model_class ||= collection_name.singularize.camelcase.constantize
end
replace_document_from(model) click to toggle source

Replace a document in the database with this model

@api private @note This will not update associated models (see {#create})

# File lib/guacamole/collection.rb, line 315
def replace_document_from(model)
  result = with_transaction(model)

  model.rev = result['_rev']

  model
end
save(model) click to toggle source

Persist a model in the collection or update it in the database, depending if it is already persisted

  • If {Model#persisted? model#persisted?} is ‘false`, the model will be saved in the collection. Timestamps, revision and key will be set on the model.

  • If {Model#persisted? model#persisted?} is ‘true`, it replaces the currently saved version of the model with its new version. It searches for the entry in the database by key. This will change the updated_at timestamp and revision of the provided model.

See also {#create create} and {#update update} for explicit usage.

@param [Model] model The model to be saved @return [Model] The provided model @example Save a podcast to the database

podcast = Podcast.new(title: 'Best Show', guest: 'Dirk Breuer')
PodcastsCollection.save(podcast)
podcast.key #=> '27214247'

@example Get a podcast, update its title, update it

podcast = PodcastsCollection.by_key('27214247')
podcast.title = 'Even better'
PodcastsCollection.save(podcast)
# File lib/guacamole/collection.rb, line 139
def save(model)
  model.persisted? ? update(model) : create(model)
end
update(model) click to toggle source

Update a model in the database with its new version

Updates the currently saved version of the model with its new version. It searches for the entry in the database by key. This will change the updated_at timestamp and revision of the provided model.

@param [Model] model The model to be updated @return [Model] The model @example Get a podcast, update its title, update it

podcast = PodcastsCollection.by_key('27214247')
podcast.title = 'Even better'
PodcastsCollection.update(podcast)
# File lib/guacamole/collection.rb, line 210
def update(model)
  return false unless model.valid?

  callbacks(model).run_callbacks :save, :update do
    replace_document_from(model)
  end
  model
end
with_transaction(model) click to toggle source
# File lib/guacamole/collection.rb, line 323
def with_transaction(model)
  Transaction.run(collection: self, model: model)
end