lib/vedeu/repositories/model.rb
# frozen_string_literal: true
module Vedeu
module Repositories
# When included into a class, provides the mechanism to store the
# class in a repository for later retrieval.
#
# @api private
#
module Model
# @!attribute [rw] repository
# @return [Vedeu::Repositories::Repository]
attr_accessor :repository
# @macro module_singleton_methods
module SingletonMethods
# @!attribute [r] repository
# @return [Vedeu::Repositories::Repository]
attr_reader :repository
# Build models using a simple DSL when a block is given,
# otherwise returns a new instance of the class including this
# module.
#
# @param attributes [Hash] A collection of attributes specific
# to the model.
# @macro param_block
# @return [Object] An instance of the model.
def build(attributes = {}, &block)
model = new(attributes)
Vedeu.log(type: :debug,
message: "DSL building: '#{model.class.name}' for " \
"'#{model.name}'")
model.deputy.instance_eval(&block) if block_given?
model
end
# Allow models to specify their repository using a class
# method.
#
# @param klass [void]
# @return [void]
def repo(klass)
@repository = klass
end
# Create and store a model with the given attributes.
#
# @param attributes [Hash] A collection of attributes specific
# to the model.
# @macro param_block
# @return [Object] An instance of the model.
def store(attributes = {}, &block)
new(attributes).store(&block)
end
end # SingletonMethods
# @macro module_included
def self.included(klass)
klass.extend(Vedeu::Repositories::Model::SingletonMethods)
end
# @note If a block is given, store the model, return the model
# after yielding.
# @todo Perhaps some validation could be added here?
# @return [void] The model instance stored in the repository.
def store(&block)
repository.store(self, &block)
end
end # Model
end # Repositories
end # Vedeu