Framework: Make Global or Universal Accessor to all the attributes of a model in Laravel 5.4 ?

Created on 19 Apr 2017  路  5Comments  路  Source: laravel/framework

  • Laravel Version: 5.4

Description:

In Laravel 5.4 , i want to make global or universal accessor to all the attributes of a model to check if the attribute value equal to NULL then return empty string instead of NULL !

for example : consider my response is an object of current login user :

$user  = Auth::user();
$user['auth_token'] = $user->api_token;

return response()->json([
     'data'          => [
                                'user'       => $user,
                            ],
     'message'   => 'success',
     'code'         => getMsgCode()
]);

the JSON response is like this :

{
  "data": {
    "user": {
      "id": 4,
      "name": "user1",
      "email": "[email protected]",
      "gender": null,
      "phone": null,
      "img": null,
      "role": "member",
      "status": 1,
      "created_at": "2017-04-09 14:44:54",
      "updated_at": "2017-04-15 16:43:51",
      "auth_token": "6csDDeFoDxWNvKGhvQcMnLsK7vRiF7FNhOGSUEYt2OmZ1OLhy4vvrpPDONk7"
    }
  },
  "message": "success",
  "code": 200
}

so as you see above in the response, for example the gender, phone or img ,, all of this attributes because there is no value to it in the database , it returned as a NULL value !!

and i don't want this null value , instead i want it to be an empty string ( "" )
like this :

{
  "data": {
    "user": {
      "id": 4,
      "name": "user1",
      "email": "[email protected]",
      "gender": "",
      "phone": "",
      "img": "",
      "role": "member",
      "status": 1,
      "created_at": "2017-04-09 14:44:54",
      "updated_at": "2017-04-15 16:43:51",
      "auth_token": "6csDDeFoDxWNvKGhvQcMnLsK7vRiF7FNhOGSUEYt2OmZ1OLhy4vvrpPDONk7"
    }
  },
  "message": "success",
  "code": 200
}

And i know about the Accessor in laravel .. for example i can do this for the img attribute, i can wirte this function ( accessor ) in User model :

public function getImgAttribute($value){
    return is_null($value) ? '' : $value;
}

but what i want is to apply an Global or Universal Accessor to all attributes instead of writing an Accessor for each attribute to handle the null value in the response.

Most helpful comment

You could override the getArrayableAttributes Model method and tinker with it a bit.

Anyway please continue on the forums, we try to keep this repo for bug reporting only.

All 5 comments

Have you tried attribute casting?
https://laravel.com/docs/5.4/eloquent-mutators#attribute-casting

@lindyhopchris :

the attribute casting applied on setting data or on getting ??

and if it on getting data, this is the only way to deal with this situation ? , as i don't want to write all the attributes that is nullable instead i want to write one code like the accessor to be applied on all attributes ..

Thanks .

You could override the getArrayableAttributes Model method and tinker with it a bit.

Anyway please continue on the forums, we try to keep this repo for bug reporting only.

From looking at the code I believe (but haven't tried myself) that the casting only affects getters, as the casting doesn't seem to be called in the setter.

https://github.com/laravel/framework/blob/5.4/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php#L511-L543

@themsaid : thank you Mohamed, its worked for me :+1: :100:

by doing this in my model :

protected function getArrayableAttributes()
    {

        foreach ($this->attributes as $key => $value) {
            if ($key == 'deleted_at') continue;

            if ( is_null($value) ) {
                $this->attributes[$key] = '';
            }
        }

        return $this->getArrayableItems($this->attributes);
    }

@lindyhopchris : thanks for your replaying :+1:

Was this page helpful?
0 / 5 - 0 ratings