🛑 Stop me if you’ve faced this decision before.
You are writing a Laravel migration.
You need to add an optional column, like unit_type.
Not every product needs a unit.
So, you have two choices:
$table->string('unit_type')->default('');$table->string('unit_type')->nullable();
I almost always chose Option 1.
Why? Fear.
I was afraid of the dreaded Trying to access property on null error in my frontend.
I just wanted to output the value without writing if statements everywhere.
Using default('') felt "safe."
But after 10 years of database design, I realized I was doing it wrong.
Here is a simple way to look at it:
Imagine a warehouse shelf. 📦
Using `nullable()` is like having no box on the shelf.
It means: "This item does not apply here." (e.g., A digital download has no weight).
Using `default('')` is like putting an empty box on the shelf.
It means: "There is a box here, but we forgot to put something inside."
When you use empty strings, you are technically "lying" to your database. You are saying there is a value (text of length 0), even when there isn’t.
Why does this matter?
❌ Queries get messy: searching for WHERE column IS NULL is standard. Searching for WHERE column = '' feels amateur.
❌ Foreign Keys: You can’t make an empty string a foreign key later.
❌ Analytics: Reports get confused between "missing data" and "empty text."
The Best Practice Solution?
Keep the database clean, and handle the "safety" in your Model.
- In your migration, use
nullable(). Let the database be accurate. - In your Laravel Model, use an Accessor:
public function getUnitTypeAttribute($value)
{
return $value ?? '';
}
This gives you the best of both worlds.
Your database stores clean NULL values.
Your frontend gets a safe empty string.
👇 What’s your preference? Do you strictly enforce NULLs, or do you sneak in defaults to save time? Let’s argue in the comments.

Top comments (4)
If you are building your database schema based on an error in the frontend, you are doing it wrong.
I wonder what else are you doing because is is easier for the frontend?
That is exactly the point I was making. For a long time, I (and many others) fell into the trap of 'coding out of fear' of frontend errors.
The transition to using nullable() is specifically about decoupling those two layers. By keeping the DB schema semantically correct and using the Model layer to handle the 'UI safety' logic, we maintain data integrity without sacrificing the developer experience. It's all about Separation of Concerns.
True you showed how to improve two layers of your application, database and backend.
The thing I wanted to emphasize is that working top-down could mean there are more serious problems with the database schema. Using an empty default could be the least of your problems.
There will be situations where having an empty string in a database is the right solution. But that has to come from the database schema design and not from frontend output.
The Top-Down trap is real. The DB should represent the reality of the data, and the Model should represent the needs of the UI. By separating those concerns, we avoid using empty strings as a 'safety blanket' and keep the schema honest.