VOOZH about

URL: https://deepwiki.com/hypervel/components/5.3-model-collections-and-resources

⇱ Model Collections and Resources | hypervel/components | DeepWiki


Loading...
Last indexed: 7 March 2026 (96fbab)
Menu

Model Collections and Resources

Overview

This document covers three key aspects of working with collections of Eloquent models:

  1. Custom Collection Resolution: How models specify custom collection classes via the #[CollectedBy] attribute
  2. Collection Methods: Enhanced methods provided by Hypervel\Database\Eloquent\Collection
  3. API Resource Transformation: Converting collections to JSON resources for API responses

The collection system bridges Eloquent models with HTTP responses, providing rich manipulation capabilities and seamless API resource transformation.

Related Pages: See page 5.1 for model foundation and page 5.2 for attribute casting.


Collection Class Architecture

Hypervel provides an enhanced Collection class that extends Hyperf's base model collection while integrating with Hypervel's support collection and resource transformation features.

Collection Class Hierarchy


Sources: src/core/src/Database/Eloquent/Collection.php1-145

The Collection class provides:

  • Hyperf Compatibility: Extends Hyperf\Database\Model\Collection for seamless integration
  • Type-Safe Operations: Maintains type information through generic annotations
  • Support Collection Bridge: Converts to Hypervel\Support\Collection via toBase() method
  • Resource Transformation: Integrates with API resource transformation via TransformsToResourceCollection trait

Key methods that bridge to support collections include pluck(), keys(), zip(), collapse(), flatten(), flip(), and pad(), all returning Hypervel\Support\Collection instances src/core/src/Database/Eloquent/Collection.php62-121


Collection Resolution Mechanism

Every model determines its collection class through a well-defined resolution chain implemented in the HasCollection trait.

Collection Resolution Flow


Sources: src/core/src/Database/Eloquent/Concerns/HasCollection.php1-61 src/core/src/Database/Eloquent/Model.php90-97

The resolution process follows this priority order:

  1. Cache Lookup: Check $resolvedCollectionClasses[static::class] for previously resolved class
  2. Attribute Resolution: Check for #[CollectedBy] attribute on the model class
  3. Property Fallback: Use the static $collectionClass property (defaults to Collection::class)
  4. Cache Storage: Store resolved class name for subsequent calls

This caching ensures reflection-based attribute resolution only happens once per model class src/core/src/Database/Eloquent/Concerns/HasCollection.php37


Specifying Custom Collection Classes

Models can specify their collection class using two approaches: a declarative attribute or a property override.

Method 1: CollectedBy Attribute (Recommended)

The #[CollectedBy] attribute provides a declarative way to specify collection classes:


Sources: src/core/src/Database/Eloquent/Attributes/CollectedBy.php1-34

The CollectedBy attribute:

Method 2: Static Property Override

Models can override the static $collectionClass property:


Sources: src/core/src/Database/Eloquent/Model.php90-97

Precedence Rules

PriorityMethodWhen Used
1Cached resultAfter first resolution for the model class
2#[CollectedBy] attributeWhen present on the model class
3$collectionClass propertyFallback when no attribute exists

The attribute takes precedence over the property tests/Core/Database/Eloquent/Concerns/HasCollectionTest.php138-147

Sources: src/core/src/Database/Eloquent/Concerns/HasCollection.php35-40 tests/Core/Database/Eloquent/Concerns/HasCollectionTest.php129-147

Attribute Inheritance Behavior

PHP attributes are not inherited by child classes. A child model must declare its own #[CollectedBy] attribute to use a custom collection:


Sources: tests/Core/Database/Eloquent/Concerns/HasCollectionTest.php109-127


Collection Resolution in Pivot Models

Both Pivot and MorphPivot models support custom collection classes through the same HasCollection trait mechanism.

Pivot Collection Support


Sources: src/core/src/Database/Eloquent/Relations/Pivot.php17-34 src/core/src/Database/Eloquent/Relations/MorphPivot.php17-34

Both Pivot and MorphPivot:

  1. Use the HasCollection trait src/core/src/Database/Eloquent/Relations/Pivot.php21 src/core/src/Database/Eloquent/Relations/MorphPivot.php21
  2. Define protected static string $collectionClass = Collection::class src/core/src/Database/Eloquent/Relations/Pivot.php34 src/core/src/Database/Eloquent/Relations/MorphPivot.php34
  3. Support the #[CollectedBy] attribute tests/Core/Database/Eloquent/Relations/PivotCollectionTest.php42-57

Custom Pivot Collections Example


Sources: tests/Core/Database/Eloquent/Relations/PivotCollectionTest.php41-78 tests/Core/Database/Eloquent/Relations/PivotCollectionTest.php95-131


Implementation Details

The newCollection Method

The newCollection() method is the entry point for all collection creation in models:

Method Signature:


Location: src/core/src/Database/Eloquent/Concerns/HasCollection.php35-40

Implementation Flow:

StepOperationCode Reference
1Check cachestatic::$resolvedCollectionClasses[static::class] ??=
2Resolve from attribute$this->resolveCollectionFromAttribute()
3Fallback to property?? static::$collectionClass
4Instantiatenew static::$resolvedCollectionClasses<FileRef file-url="https://github.com/hypervel/components/blob/96fbabf3/static#LNaN-LNaN" NaN file-path="static">Hii</FileRef>

Sources: src/core/src/Database/Eloquent/Concerns/HasCollection.php35-40

The resolveCollectionFromAttribute Method

This protected method handles reflection-based attribute resolution:

Method Signature:


Location: src/core/src/Database/Eloquent/Concerns/HasCollection.php47-59

Implementation:


The method:

  1. Creates a ReflectionClass for the model src/core/src/Database/Eloquent/Concerns/HasCollection.php49
  2. Gets all CollectedBy attributes src/core/src/Database/Eloquent/Concerns/HasCollection.php51
  3. Returns null if no attribute exists src/core/src/Database/Eloquent/Concerns/HasCollection.php53-55
  4. Instantiates the attribute and extracts collectionClass property src/core/src/Database/Eloquent/Concerns/HasCollection.php58

Sources: src/core/src/Database/Eloquent/Concerns/HasCollection.php47-59

Cache Management

The $resolvedCollectionClasses static array caches resolved collection class names per model class:

Declaration:


Location: src/core/src/Database/Eloquent/Concerns/HasCollection.php27

Cache Structure:


The cache uses static::class as the key, ensuring each model class maintains its own cached resolution src/core/src/Database/Eloquent/Concerns/HasCollection.php37

Sources: src/core/src/Database/Eloquent/Concerns/HasCollection.php22-27 src/core/src/Database/Eloquent/Concerns/HasCollection.php37

When Collections Are Created

Collections are instantiated whenever Eloquent returns multiple models:

MethodReturns CollectionCode Location
Model::all()Query result hydration
Model::get()Query result hydration
Model::find([1, 2, 3])Multiple IDs
Model::hydrate($array)Manual hydration
Model::fromQuery($sql)Raw SQL result
$relation->get()Relationship loading
$model->newCollection()Direct instantiation

Sources: src/core/src/Database/Eloquent/Model.php29-62 (PHPDoc annotations showing return types)

Collection Type Annotations

The Model class includes extensive PHPDoc annotations to provide type safety for collection-returning methods:


These annotations ensure static analysis tools understand that custom collection classes will be returned when specified src/core/src/Database/Eloquent/Model.php29-62

Sources: src/core/src/Database/Eloquent/Model.php29-62


Relationship to DataObjects

While models use collections for multiple results, individual model attributes can be cast to DataObject instances. This is handled separately by the attribute casting system.

Cast Example:


For details on DataObject and the AsDataObject caster, see DataObjects and DTOs.

Sources: src/core/src/Database/Eloquent/Casts/AsDataObject.php1-70