How to Remove Appends Attributes from Laravel Eloquent Model

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

Following the syntax to 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

It was the simplest example of using accessors in an Eloquent model. Our main motive in this post however is to display the opposite of it, that is, to remove the attribute. In other words, un-appending or detaching of attribute from an Eloquent model.

Methods 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 two 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 or view.

Method 2 – Using setAppends  method

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

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

Handling $appends using trait

Sometimes you may want to use getArrayableAppends modifier method to extend $appends array of the model. getArrayableAppends is a core modifier which one can use to modify $appends property of the 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 the User model and next time when you query User  model it should append a 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