Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Overridable Model Laravel Package

3x1io/laravel-overridable-model

A Laravel package for making Eloquent models overridable, so applications and packages can swap in custom model classes through configuration without editing vendor code. Useful for extending third-party packages while keeping your own logic separate and upgrade-safe.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the package via Composer:
    composer require 3x1io/laravel-overridable-model
    
  2. Laravel will auto-discover the service provider. Publish the config if the package exposes one:
    php artisan vendor:publish --provider="Threex1\OverridableModel\OverridableModelServiceProvider"
    
  3. Open the generated config/overridable-model.php (or the package README section on model mapping) first — this is where you register which concrete model class should replace another at resolution time.
  4. First use case: you depend on a vendor package whose User/Order model you need to extend without editing vendor/. Point the package's map at your subclass and let your code keep referencing the original class name.

Start by overriding one low-risk model (e.g. a package model with a single added scope) and verify it resolves correctly in php artisan tinker before rolling it out across the app.

Implementation Patterns

  • Config-driven overrides. Declare mappings once in the config file:
    'overrides' => [
        \Vendor\Package\Models\Order::class => \App\Models\Order::class,
    ],
    
    This keeps the replacement declarative and environment-aware (you can swap implementations per env).
  • Runtime registration. Register overrides in a service provider's boot() for cases where the target depends on tenant, feature flag, or request context:
    OverridableModel::override(VendorOrder::class, TenantOrder::class);
    
  • Subclass and extend. Your override class should extend the original model so all existing methods, casts, and relationships continue to work. Add scopes, accessors, or override booted() behavior — do not change the table unless intentional.
  • Use it as an extension seam. Typical workflows: adding a global scope for multi-tenancy, replacing a package's relationship target, or injecting a custom HasMany/BelongsTo target where the vendor model is referenced by FQCN.
  • Keep call sites unchanged. The value is that VendorOrder::query() and $user->orders continue to work; only resolution changes. Avoid sprinkling app(Order::class) calls if the package already handles static resolution.
  • Integration with container binding. Where the package resolves through the container, prefer binding the override class in a service provider so constructor injection also receives the replacement.
  • Test at the resolution boundary. Add one feature test asserting get_class(VendorOrder::query()->first()) returns your subclass — this catches registration-order bugs early.

Gotchas and Tips

  • Config caching. If you add overrides to the config file, run php artisan config:clear (and remember config:cache in deploy). Runtime-registered overrides in boot() are unaffected but must run after the package provider.
  • Provider ordering. Overrides registered in boot() depend on the package provider having booted first. If resolution fails, check bootstrap/providers.php / config/app.php ordering or use $this->app->afterResolving(...).
  • Eager loading and relationship resolution. When overriding a model that appears as a relationship target, the related model must point at the same class the package resolves — mismatches cause Class not found or silent fallback to the original. Audit hasMany/belongsTo FQCNs after adding an override.
  • Morph maps. If the overridden model is polymorphic, register it in Relation::enforceMorphMap() or update morphMap config, otherwise morphTo will return the base class.
  • Serialization and queues. Queued jobs and cached payloads serialize the resolved class name. Deploying a new override mapping is safe, but removing one can break in-flight jobs — drain queues before removing mappings.
  • IDE and static analysis. Static calls on the base class still resolve to the base class for PHPStan/IDE. Add @method/@property docblocks or a stub on the base model if you rely heavily on static analysis.
  • Migrations. Overrides change behavior, not schema. If your subclass lives on a different table, add migrations explicitly; do not assume the vendor table carries over.
  • Debugging. When an override isn't applied, dump the resolved map (config('overridable-model.overrides')) and confirm the FQCN string matches exactly (leading backslash and case sensitivity matter). Use php artisan about or a one-off tinker command to inspect the current mapping.
  • Extension points. Prefer the package's published config and container bindings over monkey-patching the service provider. If the package supports a resolver callback, that is the safest place for tenant-aware logic.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator