diff --git a/src/Illuminate/Database/Eloquent/Model.php b/src/Illuminate/Database/Eloquent/Model.php index fa5d1422cc68..d30babd93a25 100644 --- a/src/Illuminate/Database/Eloquent/Model.php +++ b/src/Illuminate/Database/Eloquent/Model.php @@ -2673,6 +2673,16 @@ protected static function resolveClassAttribute(string $attributeClass, ?string return static::$classAttributes[$cacheKey] = $property ? $instance->{$property} : $instance; } + + foreach ($reflection->getTraits() as $trait) { + $attributes = $trait->getAttributes($attributeClass); + + if (count($attributes) > 0) { + $instance = $attributes[0]->newInstance(); + + return static::$classAttributes[$cacheKey] = $property ? $instance->{$property} : $instance; + } + } } while ($reflection = $reflection->getParentClass()); } catch (Exception) { // diff --git a/tests/Database/DatabaseEloquentModelAttributesTest.php b/tests/Database/DatabaseEloquentModelAttributesTest.php index d672d05a1634..51c11bdfd124 100644 --- a/tests/Database/DatabaseEloquentModelAttributesTest.php +++ b/tests/Database/DatabaseEloquentModelAttributesTest.php @@ -447,6 +447,20 @@ public function test_trait_initializer_merges_fillable_with_attribute(): void $this->assertEqualsCanonicalizing(['name', 'email', 'phone'], $model->getFillable()); } + + public function test_trait_with_attribute_applies_to_class(): void + { + $model = new ModelUsingWithoutIncrementingTraitWithAttribute; + + $this->assertFalse($model->getIncrementing()); + } + + public function test_class_attribute_takes_precedence_over_trait(): void + { + $model = new ModelOverridingTraitConnectionAttribute; + + $this->assertSame('primary', $model->getConnectionName()); + } } enum ConnectionUnitEnum @@ -773,3 +787,24 @@ class ModelWithFillableAttributeAndTrait extends Model { use AddsPhoneFillable; } + +#[WithoutIncrementing] +trait TraitUsingWithoutIncrementingAttribute +{ +} + +class ModelUsingWithoutIncrementingTraitWithAttribute extends Model +{ + use TraitUsingWithoutIncrementingAttribute; +} + +#[Connection('secondary')] +trait TraitUsingConnectionAttribute +{ +} + +#[Connection('primary')] +class ModelOverridingTraitConnectionAttribute extends Model +{ + use TraitUsingConnectionAttribute; +}