Skip to content

Refactor Model Architecture: Introduce Base Model and Database Model Separation #372

Description

@armanist

Summary

Quantum’s current QtModel represents a database-backed Active Record model. Over time, the framework has grown a need for models that are not strictly database entities, while still preserving the existing DB-first workflow and developer experience.

This ticket proposes a minimal, backward-compatible refactoring to clearly separate:

  • a base model abstraction (lightweight, non-DB),
  • from a database-capable model (current QtModel behavior).

The goal is to improve architectural clarity and flexibility without introducing additional developer overhead, new factories, or new mental models.

Motivation

Current constraints:

  • A “model” can only exist if database infrastructure is attached.
  • ModelFactory enforces QtModel usage and throws if a model is not DB-backed.
  • This limits the ability to represent simple, transient, or computed models while reusing common model behavior.

Desired outcome:

  • Support non-DB models and DB models under a single, coherent architecture.
  • Preserve existing usage patterns (model(SomeModel::class)).
  • Avoid introducing new interfaces, flags, annotations, or developer-side boilerplate.

High-Level Design Requirements

  1. Base Model Introduction
  • Introduce a new abstract base class Model.
  • This class represents the minimal model concept in Quantum.
  • It must:
    • Be database-agnostic.
    • Contain only minimal shared behavior (e.g. attributes handling, fillable rules, serialization helpers).
    • Not depend on ORM, Database, or persistence concerns.
  • Keep the base class intentionally small to avoid framework bloat.

2. Database Model Specialization

  • The existing QtModel should become a database-specific specialization.
  • Rename conceptually (or via alias) to something like:
    • DbModel / DatabaseModel (exact naming to be decided by contributors).
  • DbModel must:
    • Extend the new base Model.
    • Contain all ORM, persistence, querying, and DB-related logic.
    • Remain abstract.
    • Preserve existing behavior and APIs as much as possible.

3. ModelFactory Behavior Adjustment

ModelFactory::get() should:

  • Always instantiate the requested model class.
  • Attach ORM infrastructure only if the model is a database model.
  • No longer throw an error if the model does not extend the DB model base class.
  • The factory must:
    • Not guess intent.
    • Not rely on reflection heuristics.
    • Not introduce new configuration flags.
  • Persistence enhancement must remain centralized and explicit.

4. Backward Compatibility

  • Existing DB models must continue to work without modification.
  • Existing helpers (model(), dynamicModel(), wrapToModel()) should continue to function as expected.
  • Any necessary signature changes (e.g. return types) must be clearly documented and justified.

5. Developer Experience (DX) Constraints

  • End developers must not be required to:
  • Implement new interfaces.
  • Declare persistence capabilities explicitly.
  • Learn multiple factories or creation patterns.
  • Model creation should remain simple and consistent.
  • Persistence should feel automatic for DB models and invisible for non-DB models.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions