How to use Laravel's Tappable trait to achieve fluency
Given the following schemas:
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:
class CreateSkillAction
{
public function execute(SkillDTO $skillData): Skill
{
...
}
}
You could easily achieve this with the following code:
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:
class Skill extends Model
{
use \Illuminate\Support\Traits\Tappable;
...
}
2. Rewrite the execute method to use the tap
method - now present on the model:
public function execute(SkillDTO $skillData): Skill
{
return Skill::create($skillData->attributes())
->tap(fn($skill)=>$skill->categories()->attach($skillData->categories));
}