roundly-consulting/attributes-for-laravel
Bring PHP 8 attributes to Laravel: declaratively register services, routes, events, and more with clean, self-documenting classes. Attributes for Laravel cuts boilerplate config and keeps behavior right next to the code it affects.
composer require <vendor>/<package>
php artisan vendor:publish --provider="<Vendor>\<Package>\<PackageServiceProvider>"
php artisan migrate
config/<package>.php). This is where the package's models, table names, and other bindings are declared. In 1.1.2 the important detail is that these configured model classes are now honored by the package's factories.$record = YourModel::factory()->create();
$this->assertInstanceOf(YourModel::class, $record);
// config/<package>.php
'models' => [
'thing' => App\Models\Thing::class,
],
$table, $fillable, relationships, and add your domain logic. Keep the package's traits and casts intact so its internals keep working.Factory::make()/create() build whichever model is configured. Use the package factories in your own tests and seeders rather than hand-rolling model instances, so swaps are exercised automatically.public function register(): void
{
config(['<package>.models.thing' => TenantThing::class]);
}
Model::create([...]) so seed data always matches the configured model and its states:
Thing::factory()->count(25)->published()->create();
resolve() or the config value), not the package's base class, so swapped models keep their hooks.assertInstanceOf failures or missing host-model attributes in factory output, upgrading to 1.1.2 is the fix. There are no breaking changes in this patch.php artisan config:clear (and re-cache in production) after changing model bindings; a stale cached config is the most common reason a swap "doesn't take."register()/setUp() before any factory call.$model still wins. If you override protected $model on a factory, that takes precedence over the config — useful for edge cases, but it bypasses the swap and can hide misconfiguration.dump(get_class(Thing::factory()->make()));
and confirm the config value with config('<package>.models.thing').newFactory() on your model to return a custom factory, add factory states/methods, and use the package's resolver/binding helper if it exposes one — these are the supported seams for host customization.How can I help you explore Laravel packages today?