Best way to handle bulk-attaching models

I have a courses model and a users model, with a many-to-many relationship between the 2. I need a way to attach many users at once to a certain course. The users that need to be attached are stored in a csv with their unique IDs. Here are a few options I came up with: - using a CSV importer: since I have a csv I could simply import it and associate that way. the problem with this method is that configuring an importer is tedious and error prone - here is another idea I came up with that I am not sure is possible in filament or not: having an action that opens a modal with an input field, this input field would take multiple space seperated user ids and then inserts them into the pivot table. this idea sounds good but I am not sure how to implement it if someone could guide me on how to implement the second option or has a better idea let me know!
2 Replies
Stormageddon, Dark Lord of All
I figured out a good solution using a custom action, here is the code for future reference:
Action::make('Attach')
->form( [
TagsInput::make('ids')
->label('IDs')
->validationAttribute('IDs')
->required()
->rules([
fn (): Closure => function (string $attribute, $value, Closure $fail) {
$records = User::whereIn('cin', $value)->pluck('cin')->toArray();
$nonExistantIds = array_diff($value, $records);

if(!empty($nonExistantIds)) {
$fail('The following :attribute don\'t exist in the the database: ' . implode(', ',$nonExistantIds));
}
},
])
->splitKeys([' '])
])->action(function (array $data, RelationManager $livewire) {

$ids = User::whereIn('cin', $data['ids'])->pluck('id')->toArray();

$course = Course::find($livewire->ownerRecord->id);

$course->users()->syncWithoutDetaching($ids);

})
Action::make('Attach')
->form( [
TagsInput::make('ids')
->label('IDs')
->validationAttribute('IDs')
->required()
->rules([
fn (): Closure => function (string $attribute, $value, Closure $fail) {
$records = User::whereIn('cin', $value)->pluck('cin')->toArray();
$nonExistantIds = array_diff($value, $records);

if(!empty($nonExistantIds)) {
$fail('The following :attribute don\'t exist in the the database: ' . implode(', ',$nonExistantIds));
}
},
])
->splitKeys([' '])
])->action(function (array $data, RelationManager $livewire) {

$ids = User::whereIn('cin', $data['ids'])->pluck('id')->toArray();

$course = Course::find($livewire->ownerRecord->id);

$course->users()->syncWithoutDetaching($ids);

})