dyrynda/laravel-nullable-fields
Keeps nullable database columns genuinely null. Add the NullableFields trait to an Eloquent model and list your nullable fields; empty strings are converted to NULL on save, keeping your Laravel data consistent across queries, filters, and relationships.
$nullable that is empty ('', empty array) is persisted as NULL instead of an empty string. The decision it really supports is where normalization lives in your architecture: at the persistence boundary (this package), at the HTTP boundary (Laravel's ConvertEmptyStringsToNull middleware), or scattered across form requests and services.'' is not NULL. The package makes "optional" mean one thing in the database, which lets you stop defending against both states in queries, exports, and API serializers.NULLs in a unique index but only one ''. Without normalization, the second user who leaves "secondary email" or "tax ID" blank gets a duplicate-key error in production. That's a support-ticket and trust cost, not an architecture cost — and it's the strongest business case for a five-minute change.WHERE col IS NULL and WHERE col = '' return different populations. Picking one convention (null) makes analytics filters, admin search, and null-coalescing logic in views predictable, and makes JSON responses consistent (null rather than "") for downstream consumers.'' to NULL while PostgreSQL and MySQL do not. Normalizing in the model keeps behavior identical when a product line migrates engines.Adopt when most of the following hold:
ConvertEmptyStringsToNull middleware is insufficient: it only covers HTTP requests, only applies globally (so you can't preserve '' as meaningful for specific fields), and is frequently disabled or bypassed in tests, jobs, and console commands.'' vs NULL has already caused a defect or a data-cleanup script.saving hook copy-pasted into a base class, and you value the readable $nullable list as documentation.Look elsewhere, or build in-house, when:
ConvertEmptyStringsToNull. That's one line of framework config versus one dependency.Model::where(...)->update() and bulk insert() bypass model events entirely, so the trait silently won't apply. If bulk paths are common, enforce the invariant with a database-level default or a CHECK/trigger strategy plus application-level normalization.BaseModel, adding a 20-line saving hook is cheaper than the governance overhead of a new dependency — and it's a legitimate answer.For executives — one paragraph: We're evaluating a small, free, MIT-licensed Laravel add-on that fixes an inconsistency in how we store blank optional fields. Today a form submitted empty may be saved as an empty string in some code paths and as a true blank in others, which has produced duplicate-record errors on optional unique fields and mismatched numbers in reporting. The package makes the behavior uniform with a one-line declaration per model. Cost is effectively zero, risk is negligible because the code is a few dozen lines and can be maintained in-house if the author ever stops, and the payoff is fewer data-integrity tickets and cleaner analytics. Recommendation: adopt as a low-ceremony engineering standard, scoped to models with genuinely optional fields.
For engineering — the short version: dyrynda/laravel-nullable-fields gives you a Nullable trait and a protected $nullable = [...] array; on saving, empty values in that list become NULL. It complements — not replaces — ConvertEmptyStringsToNull, which only covers HTTP and applies globally. Use it where optional unique columns or mixed write paths (jobs, imports, APIs) make '' vs NULL ambiguous. Caveats: model events don't fire on query-builder bulk writes, so keep those paths normalized separately; pin the version and add one regression test asserting round-trip null behavior on a model with a unique nullable column; and timebox the evaluation to under an hour. If we'd rather not carry the dependency, the fallback is a saving hook in our base model — functionally equivalent, marginally more code we own.
How can I help you explore Laravel packages today?