anas/easy-dev
Interactive Laravel code generator for complete CRUD with repository/service patterns. Auto-detects model relationships and scaffolds policies, DTOs, observers, filters, enums, API resources, routes, and more, with dry-run mode and customizable stubs.
This guide covers advanced features and use cases for Laravel Easy Dev package.
The Repository pattern provides a layer of abstraction between your business logic and data access logic.
php artisan easy-dev:repository User
Generated files:
app/Repositories/UserRepository.phpapp/Repositories/Contracts/UserRepositoryInterface.php<?php
namespace App\Repositories;
use App\Models\User;
use App\Repositories\Contracts\UserRepositoryInterface;
use Illuminate\Database\Eloquent\Collection;
class UserRepository implements UserRepositoryInterface
{
public function __construct(
protected User $model
) {}
public function getAll(): Collection
{
return $this->model->all();
}
public function findById(int $id): ?User
{
return $this->model->find($id);
}
public function create(array $data): User
{
return $this->model->create($data);
}
public function update(User $user, array $data): User
{
$user->update($data);
return $user;
}
public function delete(User $user): bool
{
return $user->delete();
}
}
The Service layer contains business logic and coordinates between controllers and repositories.
php artisan easy-dev:crud Product --with-service --with-repository
<?php
namespace App\Services;
use App\Models\Product;
use App\Services\Contracts\ProductServiceInterface;
use App\Repositories\Contracts\ProductRepositoryInterface;
class ProductService implements ProductServiceInterface
{
public function __construct(
protected ProductRepositoryInterface $repository
) {}
public function createProduct(array $data): Product
{
// Business logic validation
$this->validateBusinessRules($data);
// Transform data if needed
$transformedData = $this->transformData($data);
return $this->repository->create($transformedData);
}
protected function validateBusinessRules(array $data): void
{
// Custom business validation
if (isset($data['price']) && $data['price'] < 0) {
throw new \InvalidArgumentException('Price cannot be negative');
}
}
}
The package automatically detects relationships from:
# Auto-detect all relationships
php artisan easy-dev:sync-relations
# Detect for specific model
php artisan easy-dev:sync-relations User
Detected from:
user_id field โ belongsTo(User::class)category_id field โ belongsTo(Category::class)Detected by reverse lookup:
posts table has user_id โ User hasMany PostDetected from:
commentable_id + commentable_type โ morphTo()morphs() method// Generated polymorphic relationships
public function commentable()
{
return $this->morphTo();
}
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
Publish and customize stub templates:
php artisan vendor:publish --tag=easy-dev-stubs
Available stubs:
model.enhanced.stub - Enhanced model templatecontroller.api.stub - API controller templatecontroller.web.stub - Web controller templaterepository.stub - Repository templateservice.stub - Service templatePublish configuration:
php artisan vendor:publish --tag=easy-dev-config
Configuration options:
<?php
return [
// File generation paths
'paths' => [
'models' => app_path('Models'),
'controllers' => app_path('Http/Controllers'),
'repositories' => app_path('Repositories'),
'services' => app_path('Services'),
],
// Default options
'defaults' => [
'with_repository' => false,
'with_service' => false,
'generate_tests' => false,
],
// Template customization
'stubs' => [
'model' => 'model.enhanced',
'controller' => 'controller.api',
],
];
Generate tests along with CRUD:
php artisan easy-dev:crud Product --with-tests
Generated test files:
tests/Feature/ProductControllerTest.phptests/Unit/ProductRepositoryTest.phptests/Unit/ProductServiceTest.php<?php
namespace Tests\Feature;
use App\Models\Product;
use Tests\TestCase;
class ProductControllerTest extends TestCase
{
/** [@test](https://github.com/test) */
public function it_can_list_products()
{
Product::factory()->count(3)->create();
$response = $this->getJson('/api/products');
$response->assertOk()
->assertJsonCount(3, 'data');
}
/** [@test](https://github.com/test) */
public function it_can_create_a_product()
{
$data = [
'name' => 'Test Product',
'price' => 99.99,
];
$response = $this->postJson('/api/products', $data);
$response->assertCreated()
->assertJsonFragment($data);
}
}
php artisan easy-dev:crud Product --api-only
Features:
// Success responses
{
"data": {
"id": 1,
"name": "Product Name",
"created_at": "2024-01-01T00:00:00.000000Z"
}
}
// Error responses
{
"message": "Validation failed",
"errors": {
"name": ["The name field is required."]
}
}
Use interactive mode for guided setup:
php artisan easy-dev:make --interactive
Features:
Generate multiple CRUDs:
# Using a loop
for model in Product Order Customer; do
php artisan easy-dev:crud $model --with-repository --with-service
done
The package generates intelligent validation rules:
// Generated validation in StoreProductRequest
public function rules(): array
{
return [
'name' => 'required|string|max:255',
'email' => 'required|email|max:255',
'price' => 'required|numeric|min:0',
'is_active' => 'required|boolean',
'category_id' => 'required|integer|exists:categories,id',
];
}
Problem: Package can't find migration file Solution: Ensure migration follows Laravel naming convention
# Correct naming
create_products_table
# Incorrect naming
products_migration
Problem: Existing model not updated with relationships Solution: Use sync-relations command
php artisan easy-dev:sync-relations Product
Problem: Routes not generated or conflicting Solution: Check existing routes and use specific options
# Generate only API routes
php artisan easy-dev:crud Product --api-only
Enable debug output:
php artisan easy-dev:crud Product --verbose
For large applications with many models:
Use specific model sync:
php artisan easy-dev:sync-relations User
Generate in batches:
# Core models first
php artisan easy-dev:crud User --with-repository --with-service
# Related models
php artisan easy-dev:crud Post --with-repository
Use without-interface for simpler structure:
php artisan easy-dev:crud Product --with-repository --without-interface
Use Repository Pattern When:
Use Service Layer When:
Interactive Mode For:
Direct Commands For:
Publish Stubs When:
This guide covers the advanced features of Laravel Easy Dev. For basic usage, see the main README.
How can I help you explore Laravel packages today?