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

Action Laravel Package

laraditz/action

Define single-purpose Action classes for Laravel and Lumen to keep code DRY. Generate actions via artisan, pass data through constructor properties, and execute with handle() or a convenient static run() method. Includes a data() helper for all properties.

View on GitHub
Deep Wiki
Context7

Getting Started

Start by installing the package via Composer:

composer require laraditz/action

First Steps

  1. Generate your first action:

    php artisan make:action CreateUser
    

    This creates a new action class in app/Actions/CreateUser.php.

  2. Define the action logic:

    namespace App\Actions;
    
    use App\Models\User;
    use Laraditz\Action\Action;
    
    class CreateUser extends Action
    {
        public function __construct(
            public string $name,
            public string $email,
            public string $password
        ) {}
    
        public function handle(): void
        {
            User::create($this->data());
        }
    }
    
  3. Use the action in a controller:

    use App\Actions\CreateUser;
    
    public function store(Request $request)
    {
        $action = new CreateUser(
            name: $request->name,
            email: $request->email,
            password: $request->password
        );
        $action->handle();
    }
    

First Use Case

Replace a simple controller method with an action to encapsulate user creation logic. This immediately reduces controller bloat and makes the logic reusable across your application.


Implementation Patterns

Basic Usage Patterns

  1. Constructor Injection: Use constructor property promotion to define required inputs for the action.

    public function __construct(
        public string $title,
        public string $content
    ) {}
    
  2. Static Execution: Use the run() static method for convenience.

    CreatePost::run(
        title: 'Hello World',
        content: 'This is a post.'
    );
    
  3. Data Access: Use $this->data() to retrieve all constructor properties as an array.

    public function handle(): void
    {
        Post::create($this->data());
    }
    

Workflows

  1. Form Handling:

    public function store(Request $request)
    {
        $action = new CreatePost(
            title: $request->title,
            content: $request->content
        );
        $action->handle();
    }
    
  2. Queue Jobs:

    public function handle()
    {
        // Process a long-running task
        sleep(10);
        User::create($this->data());
    }
    

    Dispatch the job:

    CreateUser::dispatch(
        name: 'John Doe',
        email: 'john@example.com',
        password: 'password123'
    );
    
  3. API Responses: Return data from the action to use in API responses.

    public function handle(): array
    {
        $user = User::create($this->data());
        return $user->toArray();
    }
    

Integration Tips

  1. Validation: Use Laravel's FormRequest to validate inputs before passing them to the action.

    public function handle(StoreUserRequest $request)
    {
        $action = new CreateUser(
            name: $request->name,
            email: $request->email,
            password: $request->password
        );
        $action->handle();
    }
    
  2. Dependency Injection: Inject services into the action constructor.

    use App\Services\NotificationService;
    
    public function __construct(
        public string $email,
        public NotificationService $notifier
    ) {}
    
    public function handle(): void
    {
        $this->notifier->sendWelcomeEmail($this->email);
    }
    
  3. Testing: Test actions in isolation by mocking dependencies.

    public function test_create_user()
    {
        $action = new CreateUser(
            name: 'Test User',
            email: 'test@example.com',
            password: 'password123'
        );
    
        $this->assertNull($action->handle());
    }
    

Gotchas and Tips

Pitfalls

  1. No Built-in Validation: The package does not include validation logic. You must manually validate inputs or use Laravel's FormRequest classes.

  2. No Transaction Support: Actions do not automatically wrap database operations in transactions. Use Laravel's DB::transaction() if needed.

    public function handle(): void
    {
        DB::transaction(function () {
            User::create($this->data());
            Profile::create(['user_id' => $this->userId]);
        });
    }
    
  3. No Middleware: Actions cannot directly use Laravel middleware. Handle authorization/validation in controllers or requests before invoking the action.

  4. Constructor Properties Only: The package relies on constructor property promotion. Avoid adding logic to the constructor that isn't related to input data.

Debugging Tips

  1. Check Constructor Properties: If $this->data() returns unexpected values, verify the constructor properties match the inputs you're passing.

  2. Use dd() for Inspection: Debug action execution by dumping data inside the handle() method.

    public function handle(): void
    {
        dd($this->data()); // Inspect inputs
    }
    
  3. Static Method vs. Instance: Ensure you're using the correct syntax. Static run() vs. instantiating the action directly can lead to confusion.

Extension Points

  1. Custom Base Action: Extend the Action class to add shared behavior.

    namespace App\Actions;
    
    use Laraditz\Action\Action;
    use Illuminate\Support\Facades\Log;
    
    abstract class BaseAction extends Action
    {
        public function handle(): mixed
        {
            Log::info("Executing action: " . static::class);
            return parent::handle();
        }
    }
    
  2. Add Return Types: Modify the handle() method to return data for API responses or further processing.

    public function handle(): array
    {
        $user = User::create($this->data());
        return $user->toArray();
    }
    
  3. Event Dispatching: Extend actions to dispatch events after execution.

    public function handle(): void
    {
        $user = User::create($this->data());
        event(new UserCreated($user));
    }
    

Configuration Quirks

  1. Action Namespace: The make:action command places actions in app/Actions. Customize this by modifying the command or creating a custom namespace.

  2. No Config File: The package has no configuration file, making it easy to integrate but also limiting customization options.

  3. Lumen Compatibility: Ensure your Lumen project uses Laravel's service container and follows Laravel's autoloading conventions for the package to work seamlessly.

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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata