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 Better Models Laravel Package

healthengine/laravel-better-models

View on GitHub
Deep Wiki
Context7

Getting Started

Read the source before you install it. This package is archived (last release 2020-09-15), has zero dependents, and predates Laravel's native strict-mode features. For a package this small, the ideas in src/ are worth more than the dependency. Clone it, read the base model class and any traits, and decide whether you want the package or a 40-line copy in app/Support/.

  1. Check compatibility first. Open composer.json and look at the illuminate/* constraints. A 2020 release targets Laravel 6/7. Confirm what it supports before running composer require healthengine/laravel-better-models.
  2. Find the entry point. Look for the base Model subclass and/or a trait in src/, plus any publishable config (php artisan vendor:publish). "Better model defaults" almost always means: a base class that sets $guarded, $casts, key/timestamp conventions, and possibly stricter attribute/lazy-load behaviour.
  3. Adopt it through one indirection. Create app/Models/BaseModel.php that extends the package class (or uses the trait). Every model extends your BaseModel, never the vendor class directly. This is the single most important step — it gives you a one-file exit path when the package rots.
  4. Prove it on one model. Point a single, well-tested model at BaseModel, run the suite, and diff the behaviour: mass assignment, toArray() output, date serialization, generated SQL. Only then migrate the rest.

First realistic use case: you have 40 models each re-declaring $guarded = [], $casts = ['created_at' => 'datetime'], and a Uuid boot trait. This package centralises that. Start there, not with the strictness features.

Implementation Patterns

Base model as the single seam. Most day-to-day usage is "write models the same way you always did, but extend BaseModel." Keep that seam thin: only put things in BaseModel that are true for every model in your app. Anything conditional belongs in a trait applied per model.

Incremental migration, model by model. Change extends Model → extends BaseModel in small batches grouped by domain (billing, auth, catalogue), running tests between batches. A global find-and-replace across 200 models will produce a wall of failures you can't attribute.

Compensate for permissive mass assignment. If the defaults include $guarded = [], the correct pairing is FormRequest validation plus explicit $fillable on anything touching money, identity, or permissions (User, Payment, Role). Never let $request->all() reach a permissive model.

Use the defaults to shrink model files. Once $casts and key conventions are inherited, delete the boilerplate from individual models rather than leaving dead declarations that shadow the base class — duplicated $casts arrays are a classic source of "why isn't my default applying?"

Keep query helpers out of controllers. If the package ships scopes or finder helpers, call them from repositories/actions/services so the model layer stays testable and you can swap the implementation later.

Test the seam, not just the models. Add one test that instantiates every model and asserts toArray() on a factory-made instance. That single test catches most global-default regressions (serialization shape, cast errors, missing attributes) in one place.

When writing your own package, depend on illuminate/database directly and copy the relevant defaults. Do not take a dependency on an archived package from code you intend to publish.

Gotchas and Tips

The package's reason for existing is now in core. Laravel 8 added Model::preventLazyLoading() / preventAccessingMissingAttributes(); Laravel 9 consolidated these into Model::shouldBeStrict(). If the package's value proposition is strictness, your migration path is to drop it and add this to a service provider:

Model::shouldBeStrict(! app()->isProduction());

Do that instead of carrying an unmaintained dependency into Laravel 10/11.

Global defaults are global. Changing the base class changes every model's serialization, mass assignment, and hydration. Observers, Nova/Filament resources, queue payloads, and API snapshot tests all silently depend on toArray() shape. Run your API contract tests before merging.

$guarded = [] is a security decision, not a convenience. Audit it explicitly. If the package sets it globally, add a lint/CI check that flags models with permissive guarding that also accept user input directly.

Date and timezone casts. A base $casts entry for datetime changes JSON output and can shift timezones if $dateFormat or app.timezone differ. Check one endpoint's response body before and after.

UUID/ULID key defaults need matching migrations. If the base class sets $keyType = 'string' and $incrementing = false, every table must use uuid/char(36) columns and related foreign keys must match. Migrations are the failure point, not the models.

Debugging checklist when a model misbehaves after adoption:

  • (new MyModel)->getAttributes() and ->getCasts() — confirm inherited defaults actually landed.
  • DB::listen(...) or Telescope — confirm no surprise extra queries from lazy-load guards.
  • composer why-not healthengine/laravel-better-models — confirm the constraint that's blocking an upgrade.
  • Check for shadowing: a child $casts/$guarded overrides, it doesn't merge.

Extend, don't patch. If you need different behaviour, override the method in App\Models\BaseModel. Never edit vendor/. If you must fork, move the code into app/ and drop the dependency — with zero dependents and no maintainer, you are the maintainer the moment you install it.

Pin the version and set a review date. "healthengine/laravel-better-models": "1.x" with a calendar reminder to re-evaluate at your next Laravel major. Realistically, plan to remove it within one upgrade cycle.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console