Text Version of the Lesson
Now, let's see how we can add data to a many-to-many relationship. Let's say that our Product may have many Tags.
We generate the Model+Migration:
php artisan make:model Tag -m
Here's the structure, with relationship right away:
Migration
Schema::create('tags', function (Blueprint $table) { $table->id(); $table->string('name'); $table->timestamps();});
app/Models/Tag.php:
use Illuminate\Database\Eloquent\Relations\BelongsToMany; class Tag extends Model{ protected $fillable = ['name']; public function products(): BelongsToMany { return $this->belongsToMany(Product::class); }}
Also, the relationship from the other way:
app/Models/Product.php:
use Illuminate\Database\Eloquent\Relations\BelongsToMany; class Product extends Model{ // ... public function tags(): BelongsToMany { return $this->belongsToMany(Tag::class); }}
Next, we generate this simple Filament Resource:
php artisan make:filament-resource Tag --simple --generate
The result is this:

But, of course, the Tags CRUD is not the topic of this lesson. What we need to do is add tags to products. Multiple tags.
There are a few ways to do it.
Option 1. Just Attach: Select Multiple
Let's add one more field in the form of...
This section seemed to be a little less considered around creating the pivot table and the requirement to include
use Illuminate\Database\Eloquent\Relations\BelongsToMany;. I worked around these and eventually got it working but just noting it since there appears to be some missing connections in this lesson. Great course though.That is true, and I do like (and miss) some of the hand-holding sometimes, but Povilas did mention that the pivot tables would not be his emphasis topic of this lesson. Probably many ways to do it, but I just added the migration:
php artisan make:migration create_product_tagthen added the middle columns like so (there are other ways):
Schema::create('product_tag', function (Blueprint $table) { $table->id(); $table->foreignId('product_id'); $table->foreignId('tag_id'); $table->timestamps(); });Add the relationships in the models (in Product.php add):
public function tags(): BelongsToMany { return $this->belongsToMany(Tag::class); }add the inverse in Tag.php :
public function products(): BelongsToMany { return $this->belongsToMany(Product::class); }Some sample data in the intermediary (pivot) table, and it worked fine.
Thanks @johnogle to provide this instruction.
@PBTraining, I've just added the "use BelongsToMany" line of code. But, as Johnogle said, in this course I'm not hand-holding for the Laravel part, as Filament is a tool ON TOP of Laravel, which implies that you already have the relationships/tables set up. The course is already quite long even without the Laravel part, and if something is not working for you, feel free to ask questions in the comments.
As always - great tutorial Povilas, thank you. And i like the text format, i think for this type of tutorials it's the best.
As for Laravel part, I would also prefer at least to see a mention of required pivot table and similar things. It's not too many extra lines of text and code, but would totally make it clear what we're working with.
I think that instead of literal hand-holding, it would be better just to give instructions as a list on what is required to move forward. So, something like:
As a bonus, it'd be nice for there to be links either to other courses or to the Laravel docs so that people can go off and fill in gaps / refresh their knowledge and then continue.
The only thing I found a bit disruptive to learning was the fact that I wasn't specifically told what I needed to do to prepare for the lesson. So then part way through, I was kinda thinking, "hmm.. I'm going to need a pivot table here"
I definitely agree with the idea of not adding lots of extra details about how to do this though as it's out of scope. But a few signposts would be nice I think :-)
Dear Povilas, the implementation for attaching existing tags is missing in the
TagsRelationManager. While you've provided the capability to create new tags when adding a new product, the functionality to attach existing tags seems to be absent. This incompleteness in the relation manager was observed. I've also examined your source code, and it appears that this particular aspect remains the same.same question
Hi everyone, I have a question.
Select::make('tags') ->relationship('tags', 'title') ->multiple(),
When use multiple(), there is not loading tags at the beggining, for example i need select filter, and when i try to use multiple i cant choose something because it hadnt loaded.
I think it is loaded when you start typing the first symbols then it's auto-completing it. You can enable/disable that behavior with
->searchable()from what I remember. Take a look at the docs for all Select options.Thanks for an answer, I found solution in documentation, for this you can just do preload() method, in place where using multiple()
Chain
->preloadRecordSelect()method toTables\Actions\AttachAction::make()How would one Edit the AttachAction? seemd like this method is missing? if I have a pivot table with attributes, I can update the pivot attributes but not the _id fields in the the pivot table for example if I have an ingredient_recipe pivot table with attributes like quantity and unit per ingredient(row) when I add the IngredientsRelationsManager to the RecipeResource it updates the ingredients.name instead of the ingredient_id, ingredient_recipe in the pivot table the attributes are updated. thanks
Sorry, I don't exactly understand what you mean. Maybe show some demo or something.
Asking for any advice anyone has. I'm struggling to fnd the answer. Using method 1 above: If I have an additional required field on the pivot table (year) that should be populated by a text field on for submission. Any ideas on how to add it into the form?
I have tried:
But it keeps throughing an error SQLSTATE[HY000]: General error: 1364 Field 'year' doesn't have a default value
Frustrating the heck out of me cause I am sure it is stupid easy to fix.
Ooooh think I found a video on it... but it uses the relation manager (option 2). That will complicate things but meh, if it works I guess. https://www.youtube.com/watch?v=ERbpyZF8G5M
Single attaching is a PITA and not really what I am after. I'd much rather just have a simple multi select field and year field in the main form but I can't seem to get that to work.
How can I use the same form in the relation manager as on the related resource?
This feature is documented under relation managers https://filamentphp.com/docs/3.x/panels/resources/relation-managers#sharing-a-resources-form-and-table-with-a-relation-manager and Povilas made a youtube video about it today https://www.youtube.com/watch?v=gHKin-a7mPY
thank you
The Relation Manager is not shown on the Create pages, only on the Edit pages. The reason apparently is that the product id needs to be known, before tags can get added through the Relation Manager.
Hi - Great instructions, as always, from Povilas! I've set up a Panel for the user's to enter their data and am looking for a way to automatically attach the authorized user to a new model. The specific scenario is User, Teacher, and School. The Teacher belongsTo a User and the Teacher has a BelongsToMany relationship with the School. When the teacher creates a new school for herself, I want that automatically attached via the school_teacher table. This can be done manually on the Edit form, but it's an unnecessary step in my business case. Any thoughts on this? Thanks!
Hi, there are a few ways to do that.
savingeventafterSave()on your create/edit form: https://filamentphp.com/docs/3.x/panels/resources/relation-managers#importing-related-recordsBoth ways will check for a specific event to happen and then add the data you need to the model
Thanks, Modestas, this is very helpful!
I'd like to know how to get the client_name though when I created it appears the name, I tried to edit but it appears only the id of the model. does anyone know how to do it appear the name?
// This is my code of the Select form component
Select::make('audit_id') ->label('Client') ->options(AuditSchedule::with('audit.clientCertType.client')->get()->pluck('audit.clientCertType.client.client_name', 'id')) ->searchable(),
Try this:
Select::make('audit_id')
->relationship('MODEL_RELATION_NAME', 'FIELD_NAME_TO_DISPLAY')
->label('Client')
->options(AuditSchedule::with('audit.clientCertType.client')->get()->pluck('audit.clientCertType.client.client_name', 'id'))
->searchable()\
An example of one of mine:
Select::make('discipline_id')->relationship('discipline', 'name')->searchable()->preload()->required(),
Great course! A little improvement would be to add a 'link-icon' next to the headers, so in my documentation I can link directly to for example the header 'Attach and Detach Existing Tags'.
I don't think all our headers are so important and clear so people would link to them. For some of them, yes, but if we make it in all headers for all lessons in all courses, it would not make much sense.
Really great course. A question:in the table product is possibile to show only some tags? filtered by a condition? I tried using something like: ->formatStateUsing(function ($record) { return $record->tags->filter->isCurrent()->pluck('name'); }) but not working.. I need something similar in my project, where I have to show on the table only memeberships of the current year Thanks!
You can create a custom view for this and display whatever is needed inside
You mean something similar to Creating CRM with Filament 3: Step-By-Step -> Creating Tags for Customers ?? Good idea, I haven't thought to do like this, i believed there was an easiest way.. on the query level
Yes, pretty much like that!
Of course, this can be done via query, but it's a bit too much to explain how. I can only give you a direction to use
modifyQueryUsing()on the table itself, as anything else would require me to understand your database structureFirst of all thank you for your answers (and sorry for my english "scolastic", but here in Italy we aren't so good as in other european countries!).
I solved the problem with a workaround: I created a new relationship on the User model:
so I have a second relation with only the membership of the actual year and I used in the table instead of the normal memberships relation.
Just to let you know, the database has a normal User table, without strange "things", and a Membership table like this:
So I need in the users table to view only the users with a membership on the current year.
I don't know if my workaround is "elegant", but works, and it's reusable in other places!
This is actually a perfect workaround! This gives you more than just the table solution!
ps. Don't ever stress about your english - if we can understand you - it's GOOD! (we are also non-english speakers here :) )
Thanks a lot! You're a great team!!!
Hi laravel daily team! I disturb you with another problem, in the same I project:
I have races, and in every race a user could subscrive, but the price change as far is the race date (e.g. till 31/07 €10; from 01/08 to 31/08 € 15 etc..) So my idea is to create a tranches table, where I store expire date a cost, of corse a Race has many Tranches; and I think that Users and Tranches are connected with a many-to-many relationship (using pivot table). Here the db schema (just to explain easily): https://drawsql.app/teams/dr-capins/diagrams/teammanager
In theory everything works great, but in filament I have an Issue: I don't want to create a TrancheResurce (it doesn't make sense), so I manage tranches CRUD from RaceResource using a Relationship Manager (and it works correctly).
But now, how can I manage subscriptions to the race? The administrator needs to attach a user to the race (passing for one of the tranche model). Teorically I need a kind of belongsToManyThrough, because every race should have many users, but passing through the Tranche model. I really don't know hot to manage this in filament. Maybe with a page? But how?
The last resource for me is to change the db schema, connecting directly races, tranches and users in a 3-model-pivotTable, but I really dislike this solution, because the db will not be normalized anymore (in a pivot row of this table we will have user_id, race_id and tranche_id, but it's clear that race_id is redundant.
Do you think there should be a solution keeping the db schema? Is possible to "combine" to relationship? (I also look for the has-many-deep package of Stoudamire, but doesn't seems to be for my situation.
Thanks a lot for your attention.
Awesome, really I dont find any competitors to this package <3
Hi, I am wondering if it would be possible to create a simpler interface for adding /attaching tags (or related items) similar to how wordpress handles it. With the option to create hierarchical relationships
Sample
In many cases I think records would be predefined. And users should simply be able to connect them via a checkbox.
And if they need to add new they can do so.
I suppose the first method presented would be closer to this set up, but Im not sure if the check box options in a scollable field is an option within filament?
I faced one problem in this section, the new tag created in this section also attached with product by default and detach is seems working fine we can detach and it does not show not assigned tags to product. Any one please guide
Very nice tutorial, as always, and very useful comments. A very attentive userbase :-). 2 things.