Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Easy Dev Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Laravel Easy Dev v2 - Complete Documentation

Latest Version on Packagist GitHub Stars Total Downloads License

๐ŸŒŸ Overview

Laravel Easy Dev v2 is a powerful, feature-rich package that revolutionizes Laravel development by providing:

  • ๐ŸŽฏ Interactive CRUD Generation with beautiful CLI interfaces
  • ๐Ÿ—๏ธ Repository & Service Pattern implementation
  • ๐Ÿ”„ Intelligent Relationship Detection from database schema
  • ๐ŸŒ API & Web Controller generation
  • ๐Ÿงช Automated Test Generation
  • ๐ŸŽจ Customizable Templates for all generated files
  • โšก Performance Optimized code generation
  • ๐Ÿ“š Comprehensive Documentation and help system

๐Ÿ“‹ Table of Contents

  1. Installation & Setup
  2. Quick Start Guide
  3. Available Commands
  4. Interactive Mode
  5. Relationship Detection
  6. Repository & Service Patterns
  7. API Development
  8. Testing Features
  9. Configuration
  10. Customization
  11. Examples & Use Cases
  12. Best Practices
  13. Troubleshooting
  14. Contributing

๐Ÿš€ Installation & Setup

System Requirements

  • PHP: 8.1 or higher
  • Laravel: 9.0, 10.x, 11.x, or 12.x
  • Database: MySQL, PostgreSQL, or SQLite
  • Composer: Latest stable version

Installation Steps

1. Install via Composer

composer require anas/easy-dev

2. Publish Configuration (Optional)

php artisan vendor:publish --tag=easy-dev-config

3. Publish Stubs (Optional)

php artisan vendor:publish --tag=easy-dev-stubs

4. Verify Installation

php artisan easy-dev:help

You should see a beautiful help interface confirming successful installation.


โšก Quick Start Guide

Generate Your First CRUD

  1. Create a Model (if not exists):
php artisan make:model Product -m
  1. Set up your migration:
// database/migrations/xxxx_create_products_table.php
Schema::create('products', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->text('description')->nullable();
    $table->decimal('price', 8, 2);
    $table->integer('stock')->default(0);
    $table->foreignId('category_id')->constrained();
    $table->boolean('is_active')->default(true);
    $table->timestamps();
});
  1. Run Migration:
php artisan migrate
  1. Generate Complete CRUD:
php artisan easy-dev:make Product
  1. Auto-detect Relationships:
php artisan easy-dev:sync-relations --all

That's it! You now have a complete CRUD system with:

  • โœ… ProductController with all CRUD methods
  • โœ… Form Request validation classes
  • โœ… Repository and Service patterns
  • โœ… API endpoints
  • โœ… Automatic model relationships
  • โœ… Test files

๐ŸŽฎ Available Commands

Primary Commands

easy-dev:make {model}

Enhanced CRUD generator with beautiful interactive UI.

# Basic usage
php artisan easy-dev:make Product

# With all options
php artisan easy-dev:make Product --with-repository --with-service --api-only --interactive

Options:

  • --with-repository: Include Repository pattern
  • --with-service: Include Service layer
  • --without-interface: Skip interface generation
  • --api-only: Generate API controller only
  • --web-only: Generate web controller only
  • --interactive: Run in interactive mode

easy-dev:crud {model}

Classic CRUD generator with Repository and Service patterns.

# Generate complete CRUD with patterns
php artisan easy-dev:crud Product --with-repository --with-service

# API-only CRUD
php artisan easy-dev:crud Product --api-only

Utility Commands

easy-dev:repository {model}

Generate repository pattern files for existing models.

# Generate repository with interface
php artisan easy-dev:repository Product

# Repository without interface
php artisan easy-dev:repository Product --without-interface

easy-dev:api-resource {model}

Generate API resource and collection classes.

php artisan easy-dev:api-resource Product

easy-dev:sync-relations {model?}

Automatically detect and add relationships to models.

# Sync relations for specific model
php artisan easy-dev:sync-relations Product

# Sync relations for all models
php artisan easy-dev:sync-relations --all

# With polymorphic targets
php artisan easy-dev:sync-relations Comment --morph-targets=Post,Video,Image

easy-dev:add-relation {model} {type} {related}

Manually add specific relationships.

# Add belongsTo relationship
php artisan easy-dev:add-relation Post belongsTo User

# Add hasMany with custom method name
php artisan easy-dev:add-relation User hasMany Post --method=articles

# Add belongsToMany relationship
php artisan easy-dev:add-relation User belongsToMany Role

Help & Demo Commands

easy-dev:help

Display beautiful help guide with all available options.

php artisan easy-dev:help

easy-dev:demo-ui

Demonstrate the package's beautiful UI capabilities.

php artisan easy-dev:demo-ui

๐ŸŽฏ Interactive Mode

The interactive mode provides a guided, step-by-step experience for generating CRUD operations.

Starting Interactive Mode

php artisan easy-dev:make Product --interactive

Interactive Flow

  1. Model Selection: Choose or create a model
  2. Generation Options: Select what to generate
  3. Pattern Selection: Choose Repository/Service patterns
  4. API Configuration: Configure API endpoints
  5. Validation Setup: Configure form validation
  6. Relationship Detection: Auto-detect model relationships
  7. File Generation: Generate all selected files
  8. Summary Report: View generated files and next steps

Interactive Features

  • ๐ŸŽจ Beautiful Progress Bars: Visual feedback during generation
  • โšก Smart Defaults: Intelligent suggestions based on your model
  • ๐Ÿ” Live Validation: Real-time validation of inputs
  • ๐Ÿ“Š Summary Reports: Detailed reports of generated files
  • ๐Ÿš€ Quick Actions: Common actions with single keypress

๐Ÿ”„ Relationship Detection

Laravel Easy Dev v2 features intelligent relationship detection that analyzes your database schema and automatically generates appropriate Eloquent relationships.

Supported Relationships

1. BelongsTo Relationships

Detected from: Foreign key columns (e.g., user_id, category_id)

// Automatically generated in Post model
public function user()
{
    return $this->belongsTo(User::class);
}

public function category()
{
    return $this->belongsTo(Category::class);
}

2. HasMany Relationships

Detected from: Reverse foreign key relationships

// Automatically generated in User model
public function posts()
{
    return $this->hasMany(Post::class);
}

// Automatically generated in Category model
public function products()
{
    return $this->hasMany(Product::class);
}

3. BelongsToMany Relationships

Detected from: Pivot tables (tables with multiple foreign keys)

// Automatically generated when post_tag table exists
public function tags()
{
    return $this->belongsToMany(Tag::class);
}

4. Polymorphic Relationships

Detected from: _type and _id column patterns

// Morphable columns: commentable_type, commentable_id
public function commentable()
{
    return $this->morphTo();
}

// Reverse relationship
public function comments()
{
    return $this->morphMany(Comment::class, 'commentable');
}

5. Self-Referencing Relationships

Detected from: parent_id columns

// Parent/child relationships
public function parent()
{
    return $this->belongsTo(Category::class, 'parent_id');
}

public function children()
{
    return $this->hasMany(Category::class, 'parent_id');
}

Database Schema Examples

Example 1: E-commerce Schema

-- Categories table
CREATE TABLE categories (
    id BIGINT PRIMARY KEY,
    name VARCHAR(255),
    parent_id BIGINT NULL,
    FOREIGN KEY (parent_id) REFERENCES categories(id)
);

-- Products table
CREATE TABLE products (
    id BIGINT PRIMARY KEY,
    name VARCHAR(255),
    category_id BIGINT,
    user_id BIGINT,
    FOREIGN KEY (category_id) REFERENCES categories(id),
    FOREIGN KEY (user_id) REFERENCES users(id)
);

-- Product reviews (polymorphic)
CREATE TABLE reviews (
    id BIGINT PRIMARY KEY,
    content TEXT,
    reviewable_type VARCHAR(255),
    reviewable_id BIGINT,
    user_id BIGINT,
    FOREIGN KEY (user_id) REFERENCES users(id)
);

-- Product tags (many-to-many)
CREATE TABLE product_tag (
    product_id BIGINT,
    tag_id BIGINT,
    FOREIGN KEY (product_id) REFERENCES products(id),
    FOREIGN KEY (tag_id) REFERENCES tags(id)
);

Generated Relationships

Running php artisan easy-dev:sync-relations --all will generate:

Category Model:

// Self-referencing
public function parent()
{
    return $this->belongsTo(Category::class, 'parent_id');
}

public function children()
{
    return $this->hasMany(Category::class, 'parent_id');
}

// Has many products
public function products()
{
    return $this->hasMany(Product::class);
}

Product Model:

// Belongs to relationships
public function category()
{
    return $this->belongsTo(Category::class);
}

public function user()
{
    return $this->belongsTo(User::class);
}

// Many-to-many
public function tags()
{
    return $this->belongsToMany(Tag::class);
}

// Polymorphic
public function reviews()
{
    return $this->morphMany(Review::class, 'reviewable');
}

Detection Algorithms

Foreign Key Detection

  1. Explicit Constraints: foreignId()->constrained('table')
  2. Laravel Conventions: foreignId()->constrained()
  3. Column Naming: Columns ending in _id

Pivot Table Detection

  1. Naming Convention: table1_table2 format
  2. Multiple Foreign Keys: Tables with exactly 2 foreign key columns
  3. Composite Keys: Combined primary key from foreign keys

Polymorphic Detection

  1. Type Columns: Columns ending in _type
  2. ID Columns: Corresponding columns ending in _id
  3. Naming Patterns: morphable_type, commentable_type, etc.

๐Ÿ—๏ธ Repository & Service Patterns

Laravel Easy Dev v2 implements clean architecture patterns to separate concerns and improve code maintainability.

Repository Pattern

Repository Interface

interface ProductRepositoryInterface
{
    public function all(): Collection;
    public function find(int $id): ?Product;
    public function create(array $data): Product;
    public function update(int $id, array $data): Product;
    public function delete(int $id): bool;
    public function findBy(string $field, $value): Collection;
    public function paginate(int $perPage = 15): LengthAwarePaginator;
}

Repository Implementation

class ProductRepository implements ProductRepositoryInterface
{
    public function __construct(private Product $model) {}

    public function all(): Collection
    {
        return $this->model->all();
    }

    public function find(int $id): ?Product
    {
        return $this->model->find($id);
    }

    public function create(array $data): Product
    {
        return $this->model->create($data);
    }

    // ... other methods
}

Service Pattern

Service Interface

interface ProductServiceInterface
{
    public function getAllProducts(): Collection;
    public function getProductById(int $id): ?Product;
    public function createProduct(array $data): Product;
    public function updateProduct(int $id, array $data): Product;
    public function deleteProduct(int $id): bool;
    public function searchProducts(string $query): Collection;
}

Service Implementation

class ProductService implements ProductServiceInterface
{
    public function __construct(
        private ProductRepositoryInterface $repository,
        private CategoryService $categoryService
    ) {}

    public function createProduct(array $data): Product
    {
        // Business logic here
        if (isset($data['category_id'])) {
            $category = $this->categoryService->getCategoryById($data['category_id']);
            if (!$category || !$category->is_active) {
                throw new InvalidArgumentException('Invalid category selected');
            }
        }

        return $this->repository->create($data);
    }

    // ... other methods with business logic
}

Dependency Injection Setup

Service Provider Registration

// Generated in RepositoryServiceProvider
public function register(): void
{
    $this->app->bind(ProductRepositoryInterface::class, ProductRepository::class);
    $this->app->bind(ProductServiceInterface::class, ProductService::class);
}

Controller Usage

class ProductController extends Controller
{
    public function __construct(
        private ProductServiceInterface $productService
    ) {}

    public function index()
    {
        $products = $this->productService->getAllProducts();
        return view('products.index', compact('products'));
    }

public function store(StoreProductRequest $request)
    {
        $product = $this->productService->createProduct($request->validated());
        return redirect()->route('products.show', $product);
    }
}

๐ŸŒ API Development

Laravel Easy Dev v2 provides comprehensive API development features with automatic resource generation and API-specific controllers.

API Resource Generation

Product Resource

class ProductResource extends JsonResource
{
    public function toArray($request): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'description' => $this->description,
            'price' => $this->price,
            'stock' => $this->stock,
            'is_active' => $this->is_active,
            'category' => new CategoryResource($this->whenLoaded('category')),
            'created_at' => $this->created_at?->toISOString(),
            'updated_at' => $this->updated_at?->toISOString(),
        ];
    }
}

Product Collection

class ProductCollection extends ResourceCollection
{
    public function toArray($request): array
    {
        return [
            'data' => $this->collection,
            'meta' => [
                'total' => $this->total(),
                'count' => $this->count(),
                'per_page' => $this->perPage(),
                'current_page' => $this->currentPage(),
                'total_pages' => $this->lastPage(),
            ],
        ];
    }
}

API Controller

Generated API Controller

class ProductApiController extends Controller
{
    public function __construct(
        private ProductServiceInterface $productService
    ) {}

    public function index(Request $request)
    {
        $products = $this->productService->getAllProducts();
        return new ProductCollection($products);
    }

    public function show(Product $product)
    {
        return new ProductResource($product->load('category', 'tags'));
    }

    public function store(StoreProductRequest $request)
    {
        $product = $this->productService->createProduct($request->validated());
        return new ProductResource($product);
    }

    public function update(UpdateProductRequest $request, Product $product)
    {
        $product = $this->productService->updateProduct($product->id, $request->validated());
        return new ProductResource($product);
    }

    public function destroy(Product $product)
    {
        $this->productService->deleteProduct($product->id);
        return response()->json(['message' => 'Product deleted successfully']);
    }
}

API Routes

Generated API Routes

// routes/api.php
Route::apiResource('products', ProductApiController::class);

// Generates the following routes:
// GET    /api/products          - index
// POST   /api/products          - store  
// GET    /api/products/{id}     - show
// PUT    /api/products/{id}     - update
// DELETE /api/products/{id}     - destroy

API Response Examples

Product List Response

{
    "data": [
        {
            "id": 1,
            "name": "Gaming Laptop",
            "description": "High-performance gaming laptop",
            "price": "1299.99",
            "stock": 15,
            "is_active": true,
            "category": {
                "id": 2,
                "name": "Electronics"
            },
            "created_at": "2025-01-15T10:30:00.000000Z",
            "updated_at": "2025-01-15T10:30:00.000000Z"
        }
    ],
    "meta": {
        "total": 50,
        "count": 15,
        "per_page": 15,
        "current_page": 1,
        "total_pages": 4
    }
}

๐Ÿงช Testing Features

Laravel Easy Dev v2 automatically generates comprehensive test suites for your CRUD operations.

Generated Test Files

Feature Tests

class ProductControllerTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();
        $this->user = User::factory()->create();
    }

    public function test_can_view_products_index()
    {
        $products = Product::factory(3)->create();

        $response = $this->actingAs($this->user)
            ->get(route('products.index'));

        $response->assertOk()
            ->assertViewIs('products.index')
            ->assertViewHas('products');
    }

    public function test_can_create_product()
    {
        $category = Category::factory()->create();
        $productData = [
            'name' => 'Test Product',
            'description' => 'Test Description',
            'price' => 99.99,
            'stock' => 10,
            'category_id' => $category->id,
        ];

        $response = $this->actingAs($this->user)
            ->post(route('products.store'), $productData);

        $response->assertRedirect(route('products.show', Product::latest()->first()));
        $this->assertDatabaseHas('products', $productData);
    }

    public function test_can_update_product()
    {
        $product = Product::factory()->create();
        $updateData = ['name' => 'Updated Product Name'];

        $response = $this->actingAs($this->user)
            ->put(route('products.update', $product), $updateData);

        $response->assertRedirect(route('products.show', $product));
        $this->assertDatabaseHas('products', $updateData);
    }

    public function test_can_delete_product()
    {
        $product = Product::factory()->create();

        $response = $this->actingAs($this->user)
            ->delete(route('products.destroy', $product));

        $response->assertRedirect(route('products.index'));
        $this->assertDatabaseMissing('products', ['id' => $product->id]);
    }
}

API Tests

class ProductApiTest extends TestCase
{
    use RefreshDatabase;

    public function test_can_get_products_list()
    {
        Product::factory(3)->create();

        $response = $this->getJson('/api/products');

        $response->assertOk()
            ->assertJsonStructure([
                'data' => [
                    '*' => [
                        'id',
                        'name',
                        'description',
                        'price',
                        'stock',
                        'is_active',
                        'created_at',
                        'updated_at'
                    ]
                ],
                'meta' => [
                    'total',
                    'count',
                    'per_page',
                    'current_page',
                    'total_pages'
                ]
            ]);
    }

    public function test_can_create_product_via_api()
    {
        $category = Category::factory()->create();
        $productData = [
            'name' => 'API Test Product',
            'description' => 'Created via API',
            'price' => 149.99,
            'stock' => 25,
            'category_id' => $category->id,
        ];

        $response = $this->postJson('/api/products', $productData);

        $response->assertCreated()
            ->assertJsonFragment($productData);
    }
}

Unit Tests

class ProductServiceTest extends TestCase
{
    protected ProductService $productService;
    protected MockInterface $repositoryMock;

    protected function setUp(): void
    {
        parent::setUp();
        $this->repositoryMock = Mockery::mock(ProductRepositoryInterface::class);
        $this->app->instance(ProductRepositoryInterface::class, $this->repositoryMock);
        $this->productService = app(ProductService::class);
    }

    public function test_can_create_product()
    {
        $productData = [
            'name' => 'Test Product',
            'price' => 99.99,
            'stock' => 10,
        ];

        $expectedProduct = new Product($productData);
        $this->repositoryMock->shouldReceive('create')
            ->once()
            ->with($productData)
            ->andReturn($expectedProduct);

        $result = $this->pr...
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui