How to Remove Appends Attributes from Laravel Eloquent Model

In Laravel the set{Attribute}Attribute accessor methods are used to set new attributes of a model. For example we use $appends property to create popular “full_name” attribute combining “first_name” and “last_name” attributes.

This is how you define $appends property and “full_name” accessor in our App\Models\User.php Eloquent model.

namespace App\Models;

class User {
    protected $appends = ['fullname'];
    protected function getFullnameAttribute()
    {
        return "{$this->first_name} {$this->last_name}";
    }
}

Once we have set it, all we need to do is to call $user->fullname to access the full name.

$user = User::first();
$user->fullname; //prints full name

This was a very simple example of using the accessor in a Eloquent model. Our primary motive in this post however is to display the opposite of it, that is, the removal of attribute i.e. un-appending or detaching of the attribute from the model.

Way to detach or remove Appends

There are two ways to remove an attribute appended with the help of an accessor, from a model. Following are these methods.

Method 1 – Using makeHidden method

$user = User::first();
$user->makeHidden(['fullname']);

This will not include the fullname attribute in the result. However you can still access the $user->fullname in case you need it before sending request back to requester.

Method 2 – Using setAppends method

$user = User::first(); 
$user->setAppends([]);

As you see we are setting an empty array as $appends to our model. Because of this, the your next query wont include any appended attribute to query result set.

Handling $appends while Using Traits

Sometimes you may use getArrayableAppends modifier method to extend appends array for a model. getArrayableAppends is a core modifier which you can use to modify the $appends property of your eloquent model.  For example:

namespace App\Models\Traits;

trait HasProgramRoles
{
    protected function getArrayableAppends()
    {
        $this->appends = array_unique(array_merge($this->appends, ['isManager']));
        return parent::getArrayableAppends();
    }

    protected function getIsManagerAttribute()
    {
      $this->isManager = true; //decide whether this is a manager
    }
}

So use this trait in your User model and next time when you query your User model it would append new isManager attribute to the result set.

namespace App\Models;
use App\Models\Traits\HasProgramRoles;

class User
{
    use HasProgramRoles;
    protected $appends = ['fullname'];
    ....
}

When you query next time, it creates two additional attributes, fullname and isManager in your model object.

Detaching $appends via Traits

Now let’s see how we can detach appends in a trait.

namespace App\Models\Traits; 
trait HasProgramRoles {
    public static $withoutAppends = false;
    protected function getArrayableAppends() {
        if( self::$withoutAppends ){
            return [];
        }
        $this->appends = array_unique(array_merge($this->appends, ['isManager'])); 
        return parent::getArrayableAppends(); 
    } 
    protected function getIsManagerAttribute() { 
        $this->isManager = true; //decide whether this is a manager 
    } 
}

Notice the use of $withoutAppends in above definition of trait. So next time you want to query your model set the value of $withoutAppends to true and it would not append the isManager to the query.

User::$withoutAppends = true;
$user = User::first();

Doing this the isManager or fullname attributes will not be available in the $user result set.

Conclusion

In this tutorial we learned about the Laravel appends and ways to detach appends from Laravel models on the fly. I hope this tutorial was able to demonstrate the use of appends and removal of appends.

Leave a Reply