Skip to content

[13.x] Model trait initializers collide with Attribute parsing #59381

@Propaganistas

Description

@Propaganistas

Laravel Version

13.2.0

PHP Version

8.5.2

Database Driver & Version

No response

Description

When using the following trait:

trait SomeTrait
{
    protected function initializeSomeTrait()
    {
        $this->mergeAppends(['url']);
    }
}

on the following model:

#[Appends(['name'])]
class MyModel extends Model
{
    use SomeTrait;
}

The final appendable attributes are set to ['url'], even though mergeAppends() was used in the trait's initialize method. The same applies for calling mergeHidden(), mergeVisible(), mergeFillable() and mergeGuarded() in a trait initializer.

This used to work fine in Laravel 12 and below, but breaks with the current parsing implementation of Attributes. Could this be an unanticipated breaking change?


if (empty($this->appends)) {
$this->appends = static::resolveClassAttribute(Appends::class, 'columns') ?? [];
}

I've tried to remove the conditional and apply mergeAppends() here as well. That works. But when doing the same trick for fillable and guarded properties things are becoming complicated (there's a fillable precedence rule, and guarded has additional * logic). I've even considered to have all framework traits initialize before anything else, but again the guarded logic is pesky.

So I'm raising it here instead.

Steps To Reproduce

#[Appends(['name'])
class TestModel extends Model
{
    use TestTrait;
}

trait TestTrait
{
    protected function initializeTestTrait()
    {
        $this->mergeAppends(['email']);
    }
}

public function test_it()
{
    $model = new TestModel;

    $this->assertEqualsCanonicalizing(['name', 'email'], $model->getAppends()); // Currently fails.
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions