DEV Community

Cover image for Simplifying Actions in Laravel
Nasrul Hazim Bin Mohamad
Nasrul Hazim Bin Mohamad

Posted on

Simplifying Actions in Laravel

For developers looking to keep their Laravel codebase clean, maintainable, and organized, Laravel Action offers an elegant solution for encapsulating business logic into reusable action classes. This package allows you to define actions that handle complex tasks, reducing boilerplate code in controllers and making your application more maintainable and testable.

With its latest release, Laravel Action now integrates with the powerful lorisleiva/laravel-actions package, bringing additional flexibility to execute actions as controllers, jobs, or event listeners.

Do take note, both Laravel Action and lorisleiva/laravel-actions has similar names, but they serve slightly different purposes.

  • Laravel Action focuses on simplifying create and update actions with support for field transformations (like hashing and encryption), constraint-based updateOrCreate operations and I'm extending Loris Leiva package.
  • While lorisleiva/laravel-actions provides broader multi-context execution, allowing actions to be run as controllers, jobs, or listeners.

By combining lorisleiva/laravel-actions with Laravel Action’s own enhancements, you can now seamlessly manage create or update operations using customizable constraints.

In this post, we’ll explore how Laravel Action can make your codebase more efficient and easy to maintain, with a look at some of the package’s key features and examples of usage.

Why Use Laravel Action?

In complex Laravel applications, we often encounter repetitive, business-specific logic scattered across controllers, services, and models. Laravel Action provides a structured approach to encapsulate this logic in action classes, resulting in cleaner controllers, single-responsibility classes, and reusable actions.

Whether you need a custom process, a transformation, or a validation, actions make it simple to encapsulate functionality in a consistent way.

Key Features of Laravel Action

Laravel Action offers a variety of features to help you structure your application’s logic more effectively. Here are some of the highlights:

1. Flexible Property Setter

One of the standout features of Laravel Action is its dynamic property setting with the setProperty method. This allows you to set properties like hashFields, encryptFields, and constrainedBy directly on the action, simplifying the code and giving you fine control over each execution.

Example:

$action = new CreateUserAction(['name' => 'Jane Doe', 'email' => 'jane@example.com', 'password' => 'securepassword']);
$action->setProperty('hashFields', ['password']); // Hash the password
$action->setProperty('encryptFields', ['ssn']); // Encrypt SSN
$action->setProperty('constrainedBy', ['email' => 'jane@example.com']); // Use email as a unique constraint
Enter fullscreen mode Exit fullscreen mode

This flexible property setting reduces boilerplate and simplifies action configuration.

2. Field Transformation: Hashing and Encryption

With Laravel Action, you can specify fields that need to be transformed, such as hashing passwords or encrypting sensitive information. By setting hashFields and encryptFields, you can easily secure sensitive data before storing it in the database.

Example:

$inputs = [
    'name' => 'Jane Doe',
    'email' => 'jane@example.com',
    'password' => 'securepassword',
    'ssn' => '123-45-6789',
];

$action = new CreateUserAction($inputs);
$action->setProperty('hashFields', ['password']);
$action->setProperty('encryptFields', ['ssn']);
$record = $action->handle();
Enter fullscreen mode Exit fullscreen mode

After execution, password is hashed, and ssn is securely encrypted before being saved.

3. Constraint-Based updateOrCreate

Laravel Action allows you to manage updateOrCreate operations with specific constraints. This feature is especially useful for handling unique records without requiring additional queries, letting you define fields that should be treated as unique or primary keys when performing updates or inserts.

Example:

$existingUser = User::create(['email' => 'uniqueemail@example.com']);
$inputs = [
    'name' => 'Updated Name',
    'email' => 'uniqueemail@example.com',
    'password' => 'newpassword',
];

$action = new CreateUserAction($inputs);
$action->setProperty('constrainedBy', ['id' => $existingUser->id]);
$record = $action->handle();
Enter fullscreen mode Exit fullscreen mode

This will update the user record based on the unique constraint of id.

4. Extending with lorisleiva/laravel-actions for Multi-Context Execution

The integration with lorisleiva/laravel-actions adds powerful multi-context execution to Laravel Action, allowing actions to be used in various contexts. With this integration, each action can be executed:

  • As a Controller: Register an action directly as a route controller.
  • As a Job: Dispatch actions as background jobs.
  • As an Event Listener: Bind actions to handle specific events.

This multi-context capability allows you to define an action once and use it across different parts of your application.

Example:

To create a new user using an action, you can now define it as a job, a controller, or an event listener. The same action can be used in each context without modifying the core functionality.

// As an Invokable Object
$user = (new CreateUserAction(['name' => 'John Doe', 'email' => 'john@example.com']))->handle();

// As a Controller
Route::post('users', CreateUserAction::class);

// As a Job
CreateUserAction::dispatch(['name' => 'John Doe', 'email' => 'john@example.com']);

// As an Event Listener
Event::listen(UserRegistered::class, CreateUserAction::class);
Enter fullscreen mode Exit fullscreen mode

Creating an Action with Laravel Action

Creating an action is simple with the make:action command:

php artisan make:action User\\CreateOrUpdateUser --model=User
Enter fullscreen mode Exit fullscreen mode

This command creates an action class within your app’s Actions folder:

<?php

namespace App\Actions\User;

use App\Models\User;
use CleaniqueCoders\LaravelAction\ResourceAction;

class CreateOrUpdateUser extends ResourceAction
{
    public string $model = User::class;

    public function rules(): array
    {
        return [
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|unique:users,email',
            'password' => 'required|string|min:8',
        ];
    }
}
Enter fullscreen mode Exit fullscreen mode

With this setup, you can now encapsulate your business logic directly in the action, keeping your controllers and jobs lightweight.

Getting Started with Laravel Action

Installation

You can install Laravel Action via Composer:

composer require cleaniquecoders/laravel-action
Enter fullscreen mode Exit fullscreen mode

Testing

Testing your actions is straightforward, allowing you to quickly ensure that your action logic is correct.

composer test
Enter fullscreen mode Exit fullscreen mode

Upgrade Notes

  • Migrating from execute() to handle(): With version 2.1.0, we have transitioned from execute() to the more Laravel-standard handle() method, allowing greater flexibility and consistency across applications.

Conclusion

Laravel Action brings a structured, flexible approach to managing your business logic. With dynamic properties, field transformations, and multi-context execution, it’s an invaluable tool for Laravel developers who want to create clean, maintainable applications. By extending lorisleiva/laravel-actions, Laravel Action makes it simple to handle create or update operations with constraints, reducing complexity and improving reusability in your Laravel projects.

Ready to simplify your Laravel application? Get started with Laravel Action today!


Photo by Patrick Fore on Unsplash

Top comments (0)