How to use Laravel's Tappable trait to achieve fluency

Given the following schemas:
```php
Schema::create('skills', function (Blueprint $table) {
    $table->id();
    $table->string("name");
});
//pivot table
Schema::create('category_skill', function (Blueprint $table) {
    $table->id();
    $table->foreignId("skill_id")->constrained();
    $table->foreignId("category_id")->constrained();
});
//the categories table will be omitted for brevity
```
Suppose you have to write a method which created a skill, attached multiple categories to it and returned the created skill afterwards:
```php
class CreateSkillAction
{
    public function execute(SkillDTO $skillData): Skill
    {
       ...
    }
}
```

You could easily achieve this with the following code:
```php
public function execute(SkillDTO $skillData): Skill
{
    $skill = Skill::create($skillData->attributes());
    $skill->categories()->attach($skillData>categories);
    return $skill;
}
```

But if you wanted to make it a bit more fluent - akin to using fluent interfaces - you could do the following:

### 1. Add the `Tappable` trait to you model:

```php
class Skill extends Model
{
    use \Illuminate\Support\Traits\Tappable;
    ...
}
```

### 2. Rewrite the execute method to use the `tap` method - now present on the model: 
```php
public function execute(SkillDTO $skillData): Skill
{
    return Skill::create($skillData->attributes())
        ->tap(fn($skill)=>$skill->categories()->attach($skillData->categories));
}
```

Denisa Halmaghi
04 Mar 2022
« Back to post