PHPackages                             predatorstudio/laravel-attribute-code-generators - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. predatorstudio/laravel-attribute-code-generators

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

predatorstudio/laravel-attribute-code-generators
================================================

v1.1(1mo ago)04MITPHPPHP ^8.1

Since Apr 23Pushed 1mo agoCompare

[ Source](https://github.com/PredatorStudio/LaravelAttributeCodeGenerators)[ Packagist](https://packagist.org/packages/predatorstudio/laravel-attribute-code-generators)[ RSS](/packages/predatorstudio-laravel-attribute-code-generators/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (2)Dependencies (12)Versions (3)Used By (0)

Laravel Attribute Code Generators
=================================

[](#laravel-attribute-code-generators)

**v1.1**

A Laravel package that generates a full CRUD scaffold from PHP 8.1 Attributes placed directly on Eloquent models. One command reads every model in your app, inspects its attributes, and writes controllers, services, repositories, DTOs, resources, migrations, policies, observers, factories, seeders, tests, and routes — only what you asked for, nothing more.

Requirements
------------

[](#requirements)

- PHP 8.1+
- Laravel 10+

Installation
------------

[](#installation)

```
composer require predatorstudio/laravel-attribute-code-generators
```

The service provider is auto-discovered via Laravel's package auto-discovery.

Publish the config file to customise paths:

```
php artisan vendor:publish --tag=crud-generator-config
```

This creates `config/crud-generator.php` in your application.

Claude Code integration (optional)
----------------------------------

[](#claude-code-integration-optional)

Install a `/describe-attributes` slash command into your project's Claude Code environment:

```
php artisan crud:install --ai
```

This copies a prompt file to `.claude/commands/describe-attributes.md` in your project root. After restarting Claude Code the command is available as a slash command:

CommandDescription`/describe-attributes`Full reference — every attribute, its parameters, generated artifacts, and interaction map`/describe-attributes Seeder`Reference for a single attribute (case-insensitive)Configuration
-------------

[](#configuration)

After publishing the config you can adjust these keys in `config/crud-generator.php`:

KeyDefaultDescription`scan_path``app/Models`Directory scanned for models (relative to project root). All subdirectories are included recursively.`generate_php_docs``false`When `true`, every generated method gets a PHPDoc block with `@param` and `@return` annotations.`api_docs_path``docs/api`Base directory for API documentation files`api_docs_models_path``docs/api/models`Directory where per-model YAML files are saved`api_docs_main_file``docs/api/openapi.yaml`Main OpenAPI file regenerated on every `crud:sync`### Output path overrides

[](#output-path-overrides)

The `paths` key lets you change the target directory for each generator. All paths are relative to the project root.

```
'paths' => [
    'controllers'  => 'app/Http/Controllers',
    'resources'    => 'app/Http/Resources',
    'requests'     => 'app/Http/Requests',
    'services'     => 'app/Services',
    'repositories' => 'app/Repositories',
    'contracts'    => 'app/Contracts',
    'policies'     => 'app/Policies',
    'observers'    => 'app/Observers',
    'actions'      => 'app/Actions',
    'dto'          => 'app/DTO',
    'enums'        => 'app/Enums',
],
```

Example — if your services live in `app/Libs/Services`:

```
'paths' => [
    'services' => 'app/Libs/Services',
],
```

The generated `UserService` will be placed at `app/Libs/Services/UserService.php` with namespace `App\Libs\Services`.

### Scanning subdirectories &amp; automatic subpath mirroring

[](#scanning-subdirectories--automatic-subpath-mirroring)

Models can be placed in any subdirectory under `scan_path`. The namespace is inferred from the folder structure, and **every generated file mirrors the same subdirectory**:

```
app/Models/Projects/Project.php  →  App\Models\Projects\Project

```

Generated files:

```
app/Http/Controllers/Projects/ProjectController.php
app/Services/Projects/ProjectService.php
app/Repositories/Projects/ProjectRepository.php
...

```

This ensures namespaces stay consistent across the entire generated scaffold without any manual configuration.

Usage
-----

[](#usage)

Annotate your model with the attributes that describe what you want generated, then run:

```
php artisan crud:sync
```

OptionDescription`--dry-run`Preview what would be generated without writing any files`--force`Overwrite existing files (asks for confirmation per file)Available Attributes
--------------------

[](#available-attributes)

### `#[Crud]`

[](#crud)

Enables CRUD generation for the model. Optionally restricts which HTTP methods are scaffolded.

```
#[Crud]
#[Crud(methods: ['index', 'store', 'show', 'update', 'destroy'])]
```

### `#[Route]`

[](#route)

Registers the resource route under the given path. Optionally applies middleware.

```
#[Route(path: 'users')]
#[Route(path: 'users', middleware: ['auth:sanctum', 'verified'])]
```

### `#[Resource]`

[](#resource)

Generates an API resource class. Specify which fields to expose, or omit `fields` to auto-generate from the model's visible `fields()` columns (respecting `hidden: true`).

```
#[Resource]
#[Resource(fields: ['id', 'name', 'email'])]
```

### `#[Service]`

[](#service)

Generates a service class. Pass `interface: true` to also generate a contract and bind it in the service container.

```
#[Service]
#[Service(interface: true)]
```

### `#[Repository]`

[](#repository)

Generates a repository class. Pass `interface: true` to also generate a contract and bind it.

```
#[Repository]
#[Repository(interface: true)]
```

### `#[DTO]`

[](#dto)

Generates a Data Transfer Object with readonly properties, a `fromArray()` factory, and a `toArray()` method. Fields marked `hidden: true` in `fields()` are excluded.

```
#[DTO]
```

### `#[Policy]`

[](#policy)

Generates a policy class for the model.

```
#[Policy]
```

### `#[Observer]`

[](#observer)

Generates an observer class and registers it automatically.

```
#[Observer]
```

### `#[Factory]`

[](#factory)

Generates an Eloquent factory for the model with sensible faker defaults per column type.

```
#[Factory]
```

### `#[Seeder]`

[](#seeder)

Generates a database seeder that uses the model's factory to create records. The default count is 10.

```
#[Seeder]
#[Seeder(count: 50)]
```

### `#[UseSoftDeletes]`

[](#usesoftdeletes)

Adds soft-delete support: appends `$table->softDeletes()` to the generated migration and injects the `SoftDeletes` trait into the model.

```
#[UseSoftDeletes]
```

> **Note:** The attribute was renamed from `#[SoftDeletes]` to `#[UseSoftDeletes]` in v1.1 to avoid a name collision with the Eloquent `SoftDeletes` trait.

### `#[GenerateMigration]`

[](#generatemigration)

Generates a `create_*_table` migration based on the model's `fields()` method. On subsequent runs the package compares saved column names against the current `fields()` list — if new columns are found it generates an `add_columns_to_*_table` ALTER migration.

```
#[GenerateMigration]
```

### `#[ValidateFromMigration]`

[](#validatefrommigration)

Generates `StoreRequest` and `UpdateRequest` validation rules derived from the migration columns. The `UpdateRequest` automatically prepends `sometimes` to every rule, making it suitable for PATCH requests.

Fields marked `hidden: true` in `fields()` are excluded from both requests.

```
#[ValidateFromMigration]
```

### `#[BackedEnum]`

[](#backedenum)

Generates a backed enum for a field. Repeatable — add one per enum field.

```
#[BackedEnum(field: 'status', values: ['active', 'inactive'])]
#[BackedEnum(field: 'role',   values: ['admin', 'editor', 'viewer'], type: 'string')]
```

Use `filename` to override the generated class name (useful when the auto-derived name conflicts with something else):

```
#[BackedEnum(field: 'status', values: ['active', 'inactive'], filename: 'ProjectStatus')]
// generates App\Enums\ProjectStatus instead of App\Enums\ProjectStatus (default)
```

### `#[Action]`

[](#action)

Generates single-purpose action classes (`Create`, `Update`, `Delete`) for the model.

```
#[Action]
```

### `#[GenerateTest]`

[](#generatetest)

Generates a feature test for the model's CRUD endpoints.

```
#[GenerateTest]
```

---

The `fields()` method
---------------------

[](#the-fields-method)

Define the model's schema by implementing a `fields()` method. It drives migration generation, validation rules, factories, DTOs, and resource output.

```
public function fields(): array
{
    return [
        ['type' => 'id'],
        ['name' => 'title',       'type' => 'string'],
        ['name' => 'body',        'type' => 'text',      'nullable' => true],
        ['name' => 'status',      'type' => 'string',    'default' => 'draft'],
        ['name' => 'user_id',     'type' => 'foreignId'],
        ['name' => 'secret_hash', 'type' => 'string',    'hidden' => true],
        ['type' => 'timestamps'],
    ];
}
```

### Field keys

[](#field-keys)

KeyTypeDescription`name`stringColumn name`type`stringColumn type (`string`, `text`, `integer`, `boolean`, `foreignId`, `json`, `id`, `timestamps`, …)`nullable`boolAdds `nullable()` to the migration column and `nullable` to validation rules`unique`boolAdds `unique()` to the migration column`default`mixedAdds `->default(value)` to the migration column`hidden`boolExcludes the field from requests, resources, and DTOs### Explicit relation definitions

[](#explicit-relation-definitions)

For `foreignId` fields you can provide an explicit `relation` key to control how the `BelongsTo` relation is generated on the model. Without it the related model is derived automatically from the `_id` suffix.

```
['name' => 'author_id', 'type' => 'foreignId', 'relation' => [
    'model'   => 'User',      // related model class (default: auto-derived from field name)
    'local'   => 'author_id', // local key on this table (default: field name)
    'foreign' => 'id',        // key on the related table (default: id)
]]
```

When `local` or `foreign` differ from defaults the generated `belongsTo()` call includes the explicit key arguments:

```
public function author(): BelongsTo
{
    return $this->belongsTo(User::class, 'author_id', 'id');
}
```

---

Bindings provider
-----------------

[](#bindings-provider)

When `interface: true` is used on `#[Service]` or `#[Repository]`, the package writes interface-to-implementation bindings to `app/Providers/GeneratedBindingsProvider.php`.

The generated block is wrapped in marker comments so that **manually added bindings are preserved** across runs:

```
public function register(): void
{
    // @crud-generator:start
    $this->app->bind(\App\Contracts\UserServiceInterface::class, \App\Services\UserService::class);
    // @crud-generator:end

    // your manual bindings go here and are never touched
    $this->app->bind(PaymentGatewayInterface::class, StripeGateway::class);
}
```

---

Generated method signatures
---------------------------

[](#generated-method-signatures)

All generated methods include explicit return types. Enable PHPDoc blocks via config:

```
'generate_php_docs' => true,
```

Controller:

```
/** @return AnonymousResourceCollection */
public function index(): AnonymousResourceCollection { ... }

/** @return UserResource */
public function show(User $user): UserResource { ... }

/** @return Response */
public function destroy(User $user): Response { ... }
```

Service:

```
/** @return LengthAwarePaginator */
public function index(): \Illuminate\Contracts\Pagination\LengthAwarePaginator { ... }

/** @return User */
public function store(array $data): User { ... }
```

---

Full example
------------

[](#full-example)

```
