Clean Conditional Logic with Laravel's Fluent Conditionable Trait

Clean Conditional Logic with Laravel's Fluent Conditionable Trait

In the world of web development, readability often trumps cleverness. Laravel has consistently embraced this philosophy by providing elegant abstractions that transform complex logic into expressive code. The addition of the Conditionable trait to Laravel's Fluent class is a perfect example of this commitment to developer experience.

Understanding the Conditionable Trait

The Conditionable trait enables you to conditionally execute operations on an object using a fluent interface. Instead of breaking your chain of method calls with traditional if-else statements, you can use the when() and unless() methods to create code that reads almost like a natural language sentence.

Let's compare the before and after to appreciate the difference:

Before: Traditional Conditional Logic

$data = Fluent::make([
    'name' => 'Michael Nabil',
    'developer' => true,
    'posts' => 25,
]);
 
if (auth()->isAdmin()) {
    $data = $data->set('role', 'admin');
} else {
    $data = $data->forget('posts');
}

After: Fluent Conditional Logic

$data = Fluent::make([
    'name' => 'Michael Nabil',
    'developer' => true,
    'posts' => 25,
])->when(auth()->isAdmin(), function (Fluent $input) {
    return $input->set('role', 'admin');
})->unless(auth()->isAdmin(), function (Fluent $input) {
    return $input->forget('posts');
});

The second approach maintains the flow of your code without breaking the chain of operations. It reads naturally: "Make a Fluent object with these properties, when the user is an admin add the admin role, unless the user is an admin remove the posts count."

Real-World Example

Let's see how the Conditionable trait can clean up real application code when preparing data for an API response:

use Illuminate\Support\Fluent;

class UserResource
{
    public function toArray($request)
    {
        $user = $this->resource;
        
        return Fluent::make([
            'id' => $user->id,
            'name' => $user->name,
            'email' => $user->email,
            'joined_at' => $user->created_at->toDateString(),
        ])
            ->when($request->user()->can('view-statistics'), function (Fluent $data) use ($user) {
                return $data->set('post_count', $user->posts()->count())
                            ->set('comment_count', $user->comments()->count());
            })
            ->when($user->isVerified(), function (Fluent $data) {
                return $data->set('verified', true)
                            ->set('verification_date', $user->verified_at->toDateString());
            })
            ->unless($request->includesPersonalData(), function (Fluent $data) {
                return $data->forget('email');
            })
            ->toArray();
    }
}

This approach allows you to build your response data conditionally, based on permissions, user states, and request parameters, all without breaking the flow of your code.

Stay Updated with More Laravel Content

Enjoyed this article? There's plenty more where that came from! Subscribe to our channels to stay updated with the latest Laravel tips, tricks, and best practices:

Subscribe to Harris Raftopoulos

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe