How to change empty string to a null using Laravel 5.1?

All we need is an easy explanation of the problem, so here it is.

While using Laravel 5.1, I am trying to check every value before it is saved in the database using Eloquent ORM. My logic is, first trim the value, if the value is an empty string "", then to convert it to null instead of just an empty string.

I was advised to create a Trait which will override the setAttribute method for that.

So here is what I have done

I have a new folder “app\Traits” inside of a file called TrimScalarValues.php which contains the following code

<?php

namespace App\Traits;

trait TrimScalarValues
{
    public function setAttribute($key, $value)
    {
        if (is_scalar($value)) {
            $value = $this->emptyStringToNull(trim($value));
        }

        return $this->setAttribute($key, $value);
    }


    /**
     * return null value if the string is empty otherwise it returns what every the value is
     *
    */
    private function emptyStringToNull($string)
    {
        //trim every value
        $string = trim($string);

        if ($string === ''){
           return null;
        }

        return $string;
    }
}

Finally I have a app\Models\Account.php file which contains the following code

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Models\industry;
use App\Traits\RecordSignature;
use App\Traits\TrimScalarValues;


class Account extends Model
{
    use RecordSignature, TrimScalarValues;
    /**
     * The database table used by the model.
     *
     * @var string
    */
    protected $table = 'accounts';

    protected $primaryKey = 'account_id';

    const CREATED_AT = 'created_on';

    const UPDATED_AT = 'modified_on';

    const REMOVED_AT = 'purged_on';


    /**
     * The attributes that are mass assignable.
     *
     * @var array
    */
    protected $fillable = ['client_id','account_name', 'company_code', 'legal_name', 'created_by','modified_by','instrucations'];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
    */
    //protected $hidden = ['account_id', 'remember_token'];


    protected $guarded = ['account_id'];

    /**
     * Get the industry record associated with the account.
    */
    public function industry()
    {
        return $this->hasOne(industry, industry::primaryKey);
    }

    public function pk(){

        return $this->primaryKey;
    }

}

But every time I update a value, I get a white page with no error or logs.

When I modify the app\Models\Account.php and change use RecordSignature, TrimScalarValues; to use RecordSignature; then I do not get a white page but obviously the values are not trimmed and converted to null.

What am I doing wrong here?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

You can’t call $this->setAttribute() in your trait. Instead you want to call the “original” setAttribute method by using parent:::

public function setAttribute($key, $value)
{
    if (is_scalar($value)) {
        $value = $this->emptyStringToNull(trim($value));
    }

    return parent::setAttribute($key, $value);
}

Regarding the empty logs, have you checked the webserver log besides the one from the framework?

Method 2

I had the same problem and solved it by creating a middleware that filters empty input fields.

public function handle($request, Closure $next) {
    $input = $request->all();
    if ($input) {
        array_walk_recursive($input, function (&$item) {
            $item = trim($item);
            $item = ($item == "") ? null : $item;
        });
        $request->merge($input);
    }
    return $next($request);
}

Don’t forget to add your custom middleware to Http/Kernel.php

Found this at Laracasts

Method 3

You might wanna take a look at this package:
https://packagist.org/packages/iatstuti/laravel-nullable-fields

“This create a trait and allows you to easily flag attributes that should be set as null when being persisted to the database.”

I know this post is old, and at that time this package maybe didn’t exist yet.

Method 4

You can use mutator in you model.
For the field account_name mutator should looks like this:

public function setAccountNameAttribute($account_name)
{
    if(is_null($account_name))
    {
        $this->attributes['account_name'] = null;
    }
    else
    {
        $this->attributes['account_name'] = $account_name;
    }
}

And everytime when you will update or insert the record using Eloquent, account_name will be passed through this mutator.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply