lib/hanami/repository.rb in hanami-model-0.7.0 vs lib/hanami/repository.rb in hanami-model-1.0.0.beta1
- old
+ new
@@ -1,8 +1,9 @@
require 'rom-repository'
require 'hanami/model/entity_name'
require 'hanami/model/relation_name'
+require 'hanami/model/mapped_relation'
require 'hanami/model/associations/dsl'
require 'hanami/model/association'
require 'hanami/utils/class'
require 'hanami/utils/class_attribute'
@@ -105,23 +106,10 @@
#
# @see Hanami::Entity
# @see http://martinfowler.com/eaaCatalog/repository.html
# @see http://en.wikipedia.org/wiki/Dependency_inversion_principle
class Repository < ROM::Repository::Root
- # Mapper name.
- #
- # With ROM mapping there is a link between the entity class and a generic
- # reference for it. Example: <tt>BookRepository</tt> references <tt>Book</tt>
- # as <tt>:entity</tt>.
- #
- # @since 0.7.0
- # @api private
- #
- # @see Hanami::Repository.inherited
- # @see Hanami::Repository.define_mapping
- MAPPER_NAME = :entity
-
# Plugins for database commands
#
# @since 0.7.0
# @api private
#
@@ -149,28 +137,37 @@
#
# It auto-infers the underlying database table.
#
# @since 0.7.0
# @api private
- def self.define_relation # rubocop:disable Metrics/MethodLength
+ #
+ # rubocop:disable Metrics/MethodLength
+ # rubocop:disable Metrics/AbcSize
+ def self.define_relation
a = @associations
+ s = @schema
configuration.relation(relation) do
- schema(infer: true) do
- associations(&a) unless a.nil?
+ if s.nil?
+ schema(infer: true) do
+ associations(&a) unless a.nil?
+ end
+ else
+ schema(&s)
end
-
- # rubocop:disable Lint/NestedMethodDefinition
- def by_primary_key(id)
- where(primary_key => id)
- end
- # rubocop:enable Lint/NestedMethodDefinition
end
relations(relation)
root(relation)
+ class_eval %{
+ def #{relation}
+ Hanami::Model::MappedRelation.new(@#{relation})
+ end
+ }
end
+ # rubocop:enable Metrics/AbcSize
+ # rubocop:enable Metrics/MethodLength
# Defines the ampping between a database table and an entity.
#
# It's also responsible to associate table columns to entity attributes.
#
@@ -184,11 +181,11 @@
e = entity
m = @mapping
blk = lambda do |_|
model e
- register_as MAPPER_NAME
+ register_as Model::MappedRelation.mapper_name
instance_exec(&m) unless m.nil?
end
root = self.root
configuration.mappers { define(root, &blk) }
@@ -223,10 +220,31 @@
# end
def self.associations(&blk)
@associations = blk
end
+ # Declare database schema
+ #
+ # NOTE: This should be used **only** when Hanami can't find a corresponding Ruby type for your column.
+ #
+ # @since 1.0.0.beta1
+ #
+ # @example
+ # # In this example `name` is a PostgreSQL Enum type that we want to treat like a string.
+ #
+ # class ColorRepository < Hanami::Repository
+ # schema do
+ # attribute :id, Hanami::Model::Sql::Types::Int
+ # attribute :name, Hanami::Model::Sql::Types::String
+ # attribute :created_at, Hanami::Model::Sql::Types::DateTime
+ # attribute :updated_at, Hanami::Model::Sql::Types::DateTime
+ # end
+ # end
+ def self.schema(&blk)
+ @schema = blk
+ end
+
# Declare mapping between database columns and entity's attributes
#
# NOTE: This should be used **only** when there is a name mismatch (eg. in legacy databases).
#
# @since 0.7.0
@@ -266,11 +284,11 @@
self.entity_name = Model::EntityName.new(name)
class_attribute :relation
self.relation = Model::RelationName.new(name)
- commands :create, update: :by_primary_key, delete: :by_primary_key, mapper: MAPPER_NAME, use: COMMAND_PLUGINS
+ commands :create, update: :by_pk, delete: :by_pk, mapper: Model::MappedRelation.mapper_name, use: COMMAND_PLUGINS
prepend Commands
end
Hanami::Model.repositories << klass
end
@@ -362,18 +380,23 @@
# Find by primary key
#
# @return [Hanami::Entity,NilClass] the entity, if found
#
+ # @raise [Hanami::Model::MissingPrimaryKeyError] if the table doesn't
+ # define a primary key
+ #
# @since 0.7.0
#
# @example
# repository = UserRepository.new
# user = repository.create(name: 'Luca')
#
# user = repository.find(user.id)
def find(id)
- root.by_primary_key(id).as(:entity).one
+ root.by_pk(id).as(:entity).one
+ rescue => e
+ raise Hanami::Model::Error.for(e)
end
# Return all the records for the relation
#
# @return [Array<Hanami::Entity>] all the entities