Laravel: Can PHP traits add values to protected values of the model

I am using Laravel 7 and at the moment I am trying to centralize some code by using PHP traits. However, I want to have traits which e.g. also add values to the protected $attributes variable or the protected $with variable.

Why I want that? Because I want to have code reuse and not to tell every Laravel model where I use my trait to also load the relationship and add the attributes to my model. That would be quite redundant...

I already figured out a way to add values to the protected $attributes variable. However, how can I add comments to my protected $with variable?

This is the code to add values to the protected $attributes variable:

    /* Add attributes to model $appends */
    protected function getArrayableAppends()
    {
        $this->appends = array_unique(array_merge($this->appends, ['publishedComments']));

        return parent::getArrayableAppends();
    }

Kind regards

1 answer

  • answered 2020-09-22 21:04 lagbox

    Traits used by Model's can be "booted" and "initialized". Booting is a static method of adjusting the behavior usually. Initializing is done on every new instance of the model, which is what you would want to be using:

    protected function initializeYourTraitName()
    {
        // do what you need to merge into $this->appends
        // do what you need to merge in new values to $this->with
    }
    

    If you check the constructor of Illuminate\Database\Eloquent\Model you will see the call to initializeTraits.

    You would need to also define a method for booting your trait, which would make the model aware of your "initialize" method that should be called on every new instance of the model.

    protected static function bootYourTraitName()
    {
        $class = static::class;
        $method = "initializeYourTraitName";
    
        static::$traitInitializers[$class][] = $method;
    
        static::$traitInitializers[$class] = array_unique(
            static::$traitInitializers[$class]
        );
    }
    

    These are methods of your trait.

    The YourTraitName part you have to change to the name of your trait.