In Filament, a Resource is based on a single parent model and every method I call on it (including relationship('relName', 'field name')
) will look at that parent model to fetch things. I have a scenario where I need to fetch and save() multiple M:M relationships described in other models.
My models are
Company
,City
,Prefecture
withbelongsToMany
relationships defined on eachMy tables are
company_city
andcompany_prefecture
My Custom Page is
CompanyRegions
My app has basic Filament Multitenancy
By edit/view Custom Page I mean this
CompanyRegions Custom Page looks like this:
class CompanyRegions extends Page implements HasForms
{
public function mount(): void {
$tenant = Filament::getTenant();
$companyID = $tenant->id;
$companyRegions = auth()->user()->companies->find($companyID)->????;
if($companyRegions === null) {
$this->form->fill();
} else {
$this->form->fill(auth()->user()->companies->find($companyID)->regions->attributesToArray());
}
}
public function form(Form $form): Form
{
return $form
->schema([
Select::make('prefectures')
->placeholder('Select prefectures you work in')
->label('Prefectures')
->options(Prefecture::all()->pluck('prefecture_ja', 'id'))
->multiple()
->searchable()
->required(),
Select::make('cities')
->placeholder('Select cities you work in')
->label('Cities')
->options(City::all()->pluck('city_ja', 'id'))
->multiple()
->searchable()
->required(),
])
->statePath('data');
}
protected function getFormActions(): array {
return [
Action::make('save')
->label(__('filament-panels::resources/pages/edit-record.form.actions.save.label'))
->submit('Save'),
];
}
public function save(): void {
$tenant = Filament::getTenant();
$data = $this->form->getState();
$data['company_id'] = $tenant->id;
$companyID = $tenant->id;
$company = auth()->user()->companies->find($companyID);
$Entry = $company->???;
if ($company->??? === null) {
$Entry = new ModelsCompanyRegions;
$Entry->fill($data);
$Entry->save($data);
Notification::make()
->success()
->title('Entry Created')
->send();
} else {
$Entry->update($data);
Notification::make()
->success()
->title('Entry Updated)
->send();
}
}
}
I tried:
Saving child models in
$model2
$model3
variables and doing something likeSelect::make('Cities')->relationship($model2->cities, 'name'),
Consulting ChatGPT. It ended up hallucinating a relatedModel method (I tested the hypothesis that it just might be deprecated by checking the official documentation for previous versions and via simple web search)
Select::make('Cities') ->relationship('cities') **->relatedModel(City::class)** ->searchable() ->sortable(), Select::make('Prefectures') ->relationship('prefectures') **->relatedModel(Prefecture::class)** ->searchable() ->sortable(),
Asking around on other forums and trying to find a YouTube video or a Filament course that tackles an issue like mine.
And that's only fetching the data. For now I can only assume in order to save it I'll have to do something like this. And then populating it properly.