Skip to content

Conversation

@binaryfire
Copy link
Contributor

This PR adds Laravel-style #[ObservedBy] attribute support to Hypervel, allowing observers to be declared directly on model classes.

Features

#[ObservedBy] Attribute

Declare observers directly on your models:

use Hypervel\Database\Eloquent\Attributes\ObservedBy;
use Hypervel\Database\Eloquent\Model;

#[ObservedBy(UserObserver::class)]
class User extends Model {}

// Multiple observers via array
#[ObservedBy([AuditObserver::class, CacheObserver::class])]
class Post extends Model {}

// Or multiple attributes (repeatable)
#[ObservedBy(AuditObserver::class)]
#[ObservedBy(CacheObserver::class)]
class Comment extends Model {}

Inheritance Support

Observers declared on parent classes are automatically inherited by children:

#[ObservedBy(AuditObserver::class)]
abstract class BaseModel extends Model {}

#[ObservedBy(UserObserver::class)]
class User extends BaseModel {}
// User gets both AuditObserver and UserObserver

Pivot Model Support

This PR also adds observer support to Pivot and MorphPivot models, similar to laravel. This was previously missing in Hypervel:

#[ObservedBy(RoleUserObserver::class)]
class RoleUser extends Pivot {}

// Service provider registration now works too
RoleUser::observe(RoleUserObserver::class);

Changes

New Files

  • src/core/src/Database/Eloquent/Attributes/ObservedBy.php - The attribute class
  • tests/Core/Database/Eloquent/Concerns/HasObserversTest.php - Tests (13 tests, 16 assertions)

Modified Files

  • src/core/src/Database/Eloquent/Concerns/HasObservers.php - Added bootHasObservers() and resolveObserveAttributes()
  • src/core/src/Database/Eloquent/Relations/Pivot.php - Added HasObservers trait
  • src/core/src/Database/Eloquent/Relations/MorphPivot.php - Added HasObservers trait

Implementation Notes

Laravel puts observer functionality in HasEvents, but Hypervel already has a separate HasObservers trait. This PR extends that existing pattern.

For pivot models, Laravel's Pivot extends Model directly, so it inherits observer support automatically. Hypervel's Pivot extends Hyperf's Pivot (which extends Hyperf's Model), so we add the HasObservers trait directly to Pivot and MorphPivot to achieve the same result.

Testing

All tests pass:

  • HasObserversTest - 13 tests covering attribute resolution, inheritance, and pivot support
  • ObserverManagerTest - Existing tests still pass
  • ModelListenerTest - Existing tests still pass

- Add ObservedBy attribute for declaring observers on model classes
- Add bootHasObservers() and resolveObserveAttributes() to HasObservers trait
- Support inheritance: observers on parent classes apply to children
- Add HasObservers trait to Pivot and MorphPivot (enables ::observe() on pivot models)
- Add comprehensive tests for all scenarios
@binaryfire binaryfire changed the title Add #[ObservedBy] attribute support feat: Add #[ObservedBy] attribute support Dec 30, 2025
Extends resolveObserveAttributes() to collect #[ObservedBy] attributes
from traits in addition to parent classes and the class itself.

The resolution order is: parent class observers -> trait observers -> class observers.

This allows traits to declare their own observers that will be automatically
registered on any model using the trait, e.g.:

    #[ObservedBy(AuditObserver::class)]
    trait Auditable { }

    class Invoice extends Model {
        use Auditable; // Automatically gets AuditObserver
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant