mit einem Klick
repositories
Repository pattern for translating between ORM rows and domain entities
Menü
Repository pattern for translating between ORM rows and domain entities
| name | repositories |
| description | Repository pattern for translating between ORM rows and domain entities |
Repositories sit between domain entities and the ORM. They are the only
place in the application where Database::*Orm may be referenced outside
of app/infrastructure/database/orm/.
Inline example: ./prompt_logs.rb
Repository::For./for.rb is the single entry point for looking up a repository
from an entity. Every new repository must be registered there:
require_relative '<new_repo>' line at the top of for.rb.Entity::<Name> => <Repos> row to the ENTITY_REPOSITORY map.Callers then resolve a repository in one of two ways:
Repository::For.klass(Entity::PromptLog) # => Repository::PromptLogs
Repository::For.entity(prompt_log_instance) # => Repository::PromptLogs
This keeps services and request objects free of require_relative chains
into the repositories directory — they ask For and get back the right
class. If For.klass returns nil for an entity, the entity is not
persistable; do not add ad-hoc fallbacks at the call site, register it
properly instead.
A repository for Entity::Foo should expose, at minimum:
| Method | Input | Output | Purpose |
|---|---|---|---|
create(entity) | Entity::Foo | persisted Entity::Foo (with id, created_at) | insert |
find_* (e.g. find_all) | filter args | Entity::Foo or Array<Entity::Foo> | query |
rebuild_entity(db_resource) | ORM row or nil | Entity::Foo or nil | shared funnel used by all the above |
Additional methods are added as workflows demand — for example
Repository::PromptLogs.update(id, attrs) exists for partial updates by id.
New methods must still take / return entities (or primitives like id),
never raw ORM rows.
Sequel::Model
instances outward. rebuild_entity is the single funnel that enforces
this.rebuild_entity must defend against nil. Callers rely on it returning
nil cleanly so Repository.update(missing_id, ...) and similar dead-end
lookups do not raise.Tyla::Repository::*, class methods (class << self) —
repositories are stateless.Sequel::Model to a service so the service can call .update
on it. Add a repository method (Repository::PromptLogs.update(id, attrs))
instead.if user.allowed? style decisions inside the repository. Move that to the
service or a policy.Request contracts validate input AND map external API names onto domain entities
Domain-Driven Design architecture patterns and conventions for this project
Roar::Decorator representers that turn domain entities into JSON
Presentation layer serializes domain entities to wire formats (JSON, etc.)
How orm/ and repositories/ split responsibility in app/infrastructure/database/
When to use Dry::Struct DTO entities vs. plain Ruby class entities in domain/entities/