lib/upgrow/basic_repository.rb in upgrow-0.0.2 vs lib/upgrow/basic_repository.rb in upgrow-0.0.3

- old
+ new

@@ -3,43 +3,70 @@ module Upgrow # Base class for Repositories. It offers a basic API for the state all # Repositories should have, as well as the logic on how to materialize data # into Models. class BasicRepository + class << self + attr_writer :base + attr_writer :model_class + + # model_class [Class] the Model class to be used to map and return the + # materialized data as instances of the domain. Defaults to a constant + # derived from the Repository class' name. For example, a `UserRepository` + # will have its default Model class set to `User`. + # + # @return [Class] the Repository Model class. + def model_class + @model_class || default_model_class + end + + # the base object to be used internally to retrieve the persisted data. + # For example, a base class in which queries can be performed for a + # relational database adapter. Defaults to `nil`. + # + # @return [Object] the Repository base. + def base + @base || default_base + end + + private + + def default_base; end + + def default_model_class + model_class_name = name.delete_suffix('Repository') + Object.const_get(model_class_name) + end + end + attr_reader :base, :model_class # Sets the Basic Repositorie's state. - # - # @param base [Object] the base object to be used internally to retrieve the - # persisted data. For example, a base class in which queries can be - # performed for a relational database adapter. Defaults to `nil`. - # - # @param model_class [Class] the Model class to be used to map and return - # the materialized data as instances of the domain. Defaults to a constant - # derived from the Repository class' name. For example, a `UserRepository` - # will have its default Model class set to `User`. - def initialize(base: default_base, model_class: default_model_class) - @base = base - @model_class = model_class + def initialize + @base = self.class.base + @model_class = self.class.model_class end # Represents the raw Hash of data attributes as a Model instance from the # Repositorie's Model class. # + # @param model_class_or_attributes [Class, Hash<Symbol, Object>] the Model + # class to be instantiated, in case it is a different class than the + # Repositorie's Model class, or the list of attributes the model will + # have, in case the Model class is the Repositorie's Model class. # @param attributes [Hash<Symbol, Object>] the list of attributes the Model - # will have. + # will have, in case the Model to be instantiated is passed as the first + # argument. # # @return [Model] the Model instance populated with the given attributes. - def to_model(attributes = {}) - model_class.new(**attributes.transform_keys(&:to_sym)) - end + def to_model(model_class_or_attributes, attributes = {}) + model_class = model_class_or_attributes - private + if model_class_or_attributes.respond_to?(:transform_keys) + model_class = self.model_class + attributes = model_class_or_attributes + end - def default_base; end - - def default_model_class - model_class_name = self.class.name[/\A(.+)Repository\z/, 1] - Object.const_get(model_class_name) + model_class.new(**attributes.transform_keys(&:to_sym)) end end end