Install the Spatie tags package according to the instructions.
https://filamentphp.com/docs/2.x/spatie-laravel-tags-plugin/installation
As standard, you can create or apply tags without types. But I wanted to separate tags into types, so this is what I did.
This requires a new model to be created.
This new model will extend the Spatie\Tag
model, and be used whenever you want to get tags of this type.
E.g, If you want to have a tag type of ‘skill’, create a new model called Skill.php
You need to extend Spatie\Tag model and set the table name like this:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory;use Spatie\Tags\Tag as SpatieTag; class Skill extends SpatieTag{ use HasFactory; //optional protected $table = 'tags';}
Now you need to add a booted
method to both scope the retrieval of tags, and intercept the creating
of tags to add the tag type.
This goes in your new ‘tag’ model (the one you just created above).
In the example below, I want the type to be skill
. (Replace this with whatever you want your type to be.)
// Be sure to import this class:use Illuminate\Database\Eloquent\Builder; class Skill extends SpatieTag{ protected static function booted() { // Only apply when there's an authenticated user if (auth()->check()) { static::addGlobalScope('skills', function (Builder $builder) { $builder->where('type', 'skill'); }); static::creating(function ($model) { $model->type = 'skill'; }); } }}
Now go to the model that you want to associate with this new tag type.
Firstly, if you haven’t already, ensure you are using the HasTags
trait from the Spatie Tags package.
use Spatie\Tags\HasTags; class Guest extends Model{ use HasFactory, SoftDeletes, **HasTags**;
Then add a method to this class to tell Spatie Tag package that you are using a new model.
use Spatie\Tags\HasTags; class Guest extends Model{ use HasFactory, SoftDeletes, HasTags; **public static function getTagClassName(): string{ return Skill::class;}**
In my example, I wanted a guest to have skills.
So in my Guest.php
model, I add the following method:
public function skills(): MorphToMany{ return $this ->morphToMany(self::getTagClassName(), 'taggable', 'taggables', null, 'tag_id') ->orderBy('order_column');}
NOTE: The original tags()
method still exists in the trait, but won’t work unless you redefine the relationship.
So if you get an error message like the following, then you’ve forgotten to add this last step!
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'taggables.skill_id' in 'field list'
That’s it. You can now use this new skills()
relationship in the select
form field.
Select::make('skills') ->relationship('skills', 'name') //The relationship you just created ->createOptionForm([ TextInput::make('name') ->required() ]) ->multiple() ->preload() ->placeholder('Type to search or add new using \'+\' button on the right'),
No comments yet…