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