F
Filament14mo ago
Avriant

Custom Page (single page edit/view, no table view) saving 2 many-to-many relationships possible?

My second Filament project, first V3 project. I ask very stupid questions from time to time, bear with me 🙇‍♂️ I want: To save a bunch of IDs for cities and prefectures as M:M relationship (company_prefectures and company_cities) using Filament Custom Page (by Custom Page I mean single page edit/view, no table view) Solution 1? I can save it as 2 separate multiselect JSONs with tenant ID attached in a migration as below:
Schema::create('company_regions', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(Company::class, 'company_id')->cascadeOnDelete();
$table->json('prefectures');
$table->json('cities');
$table->timestamps();
});
Schema::create('company_regions', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(Company::class, 'company_id')->cascadeOnDelete();
$table->json('prefectures');
$table->json('cities');
$table->timestamps();
});
But I hear JSONs are extremely heavy, especially if you need to be able to quickly search through these IDs. Solution 2? Save it as M:M, but I've no idea how to do it using a single custom page (Making 2 separate pages for 2-4 multiselect inputs seems like an overkill to me and is not a good UX). If it's possible, I understand I'll need 2 separate M:M tables (company_prefecture and company_city?) But if I try to pull something like that off, ->relationship returns null in my case. Any advice would be much appreciated
1 Reply
Avriant
AvriantOP14mo ago
My custom page (saving IDs as JSONs)
class CompanyRegions extends Page implements HasForms
{
public function mount(): void {
$tenant = Filament::getTenant();
$companyID = $tenant->id;
$companyRegions = auth()->user()->companies->find($companyID)->regions;

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('活動県選択')
->label('県')
->options(Prefecture::all()->pluck('prefecture_ja', 'id'))
->multiple()
->searchable()
->required(),
Select::make('cities')
->placeholder('活動市選択')
->label('市')
->options(City::all()->pluck('city_ja', 'id'))
->multiple()
->searchable()
->required(),
])
->statePath('data');
}
class CompanyRegions extends Page implements HasForms
{
public function mount(): void {
$tenant = Filament::getTenant();
$companyID = $tenant->id;
$companyRegions = auth()->user()->companies->find($companyID)->regions;

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('活動県選択')
->label('県')
->options(Prefecture::all()->pluck('prefecture_ja', 'id'))
->multiple()
->searchable()
->required(),
Select::make('cities')
->placeholder('活動市選択')
->label('市')
->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('保存'),
];
}

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->regions();

// Check if a "general" entry already exists for this company
if ($company->regions === null) {
// If no "member" entry exists, create a new one
$Entry = new ModelsCompanyRegions;
$Entry->fill($data);
$Entry->save($data);

Notification::make()
->success()
->title('登録完了')
->send();
} else {
$Entry->update($data);
Notification::make()
->success()
->title('更新完了')
->send();
}
}
}
protected function getFormActions(): array {
return [
Action::make('save')
->label(__('filament-panels::resources/pages/edit-record.form.actions.save.label'))
->submit('保存'),
];
}

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->regions();

// Check if a "general" entry already exists for this company
if ($company->regions === null) {
// If no "member" entry exists, create a new one
$Entry = new ModelsCompanyRegions;
$Entry->fill($data);
$Entry->save($data);

Notification::make()
->success()
->title('登録完了')
->send();
} else {
$Entry->update($data);
Notification::make()
->success()
->title('更新完了')
->send();
}
}
}
Want results from more Discord servers?
Add your server