F
Filament13mo ago
Damien

What is the best way to save data into multiple tables from one form?

Firstly, I did a search within the other help topics and struggled to find anything so apologies if I missed an example! For context, I have 2 tables within my database, projects and project_addresses. When creating a new project, I am using a wizard to capture 3 lots of information project details, admin details and address details the later will be stored in the project_addresses table and separate from the project details and admin details that are stored within the projects table. Also I apologise if this is in the documentation, the only thing I found which seemed somewhat related was https://filamentphp.com/docs/3.x/forms/advanced#saving-data-to-relationships but this moves on to talking about loading data which threw me off.
24 Replies
Saade
Saade13mo ago
you need ->relation('addesses') on the group of fields that belongs to the project_addresses table
Damien
DamienOP13mo ago
I don't completely follow, here is my wizard step:
$delivery = Wizard\Step::make('Delivery')->schema([
Forms\Components\Select::make('type')
->preload()
->required(),
Forms\Components\TextInput::make('addr_line_1')
->required()
->maxLength(255),
Forms\Components\TextInput::make('addr_line_2')
->required()
->maxLength(255),
Forms\Components\TextInput::make('city')
->required()
->maxLength(255),
Forms\Components\TextInput::make('postcode')
->required()
->maxLength(255),
]);
$delivery = Wizard\Step::make('Delivery')->schema([
Forms\Components\Select::make('type')
->preload()
->required(),
Forms\Components\TextInput::make('addr_line_1')
->required()
->maxLength(255),
Forms\Components\TextInput::make('addr_line_2')
->required()
->maxLength(255),
Forms\Components\TextInput::make('city')
->required()
->maxLength(255),
Forms\Components\TextInput::make('postcode')
->required()
->maxLength(255),
]);
I've tried adding the relation to a couple of different elements but it only exists on a few, such as select elements for example.
Saade
Saade13mo ago
which of these components belongs to the project_addresses table?
Damien
DamienOP13mo ago
This whole step belongs to project_address I have 2 other steps that belong to projects table. Hmm thinking about it, I don't know if this is the best flow for what I want or need at the moment as I need the project.id which doesn't actually exist at this point to be added to the project_addresses row too. Sorry toeknee, I don't know what I am supposed to be looking at here or whether I phrased my question correctly as that doesn't seem relevant to what I am asking. Apologies if I misunderstood.
toeknee
toeknee13mo ago
You haven't sorry, I pasted this by mistake it was for another chat
Damien
DamienOP13mo ago
haha not to worry!
toeknee
toeknee13mo ago
So on the model if you have a relationship 'address' you should be able to use something like:
$delivery = Wizard\Step::make('Delivery')->schema([
Group::make([
Forms\Components\Select::make('type')
->preload()
->required(),
Forms\Components\TextInput::make('addr_line_1')
->required()
->maxLength(255),
Forms\Components\TextInput::make('addr_line_2')
->required()
->maxLength(255),
Forms\Components\TextInput::make('city')
->required()
->maxLength(255),
Forms\Components\TextInput::make('postcode')
->required()
->maxLength(255),
])->relationship('address')
]);
$delivery = Wizard\Step::make('Delivery')->schema([
Group::make([
Forms\Components\Select::make('type')
->preload()
->required(),
Forms\Components\TextInput::make('addr_line_1')
->required()
->maxLength(255),
Forms\Components\TextInput::make('addr_line_2')
->required()
->maxLength(255),
Forms\Components\TextInput::make('city')
->required()
->maxLength(255),
Forms\Components\TextInput::make('postcode')
->required()
->maxLength(255),
])->relationship('address')
]);
Damien
DamienOP13mo ago
Ah thank you toeknee! I did start looking at this I think but I think I stopped because I am unsure if it supports one to many? (one project, many address) but please correct me if I am wrong! In the meantime I will look at the code you shared 🙂
toeknee
toeknee13mo ago
One to many would need a repeater instead of group 🙂 so you can add multiple addresses for that one instance
Damien
DamienOP13mo ago
Checking out the repeater now, thank you! Definitely on the right path! Just got to figure out how I can get my enum values for the type select.
toeknee
toeknee13mo ago
->options() ?
Damien
DamienOP13mo ago
Ah hit an error!
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Project Addresses' in 'field list'
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Project Addresses' in 'field list'
There is no column in the projects table that references an address. Instead, in the project_addresses table, there is a column for project_id Is this back to front? yeah, got there, was being daft!
toeknee
toeknee13mo ago
Can I see your code?
Damien
DamienOP13mo ago
sure, is there anything specific that would help further? (rather than me blindly sharing stuff that is of no help)
toeknee
toeknee13mo ago
Not particularly I just need to see how you have the schema build as it shouldn't be looking for Project Addresses ? it should be a structure column as I assume you don't have the column name as Project Addresses anywhere
Damien
DamienOP13mo ago
Okay, let me grab some code, 2 minutes. Here is my form, I've removed the first 2 schemas as it is too big for the character count for discord otherwise.
public static function form(Form $form): Form
{
$project = Wizard\Step::make('Project')->schema([ ... ]);

$admin = Wizard\Step::make('Admin')->schema([ ... ]);

$delivery = Wizard\Step::make('Addresses')->schema([
Repeater::make('Project Addresses')->schema([
Forms\Components\Select::make('type')
->options(ProjectAddressTypeEnum::class)
->required(),
Forms\Components\TextInput::make('address_line_1')
->required()
->maxLength(255),
Forms\Components\TextInput::make('address_line_2')
->maxLength(255),
Forms\Components\TextInput::make('city')
->required()
->maxLength(255),
Forms\Components\TextInput::make('postcode')
->required()
->maxLength(255),
]),
]);

return $form->schema([
Wizard::make(['Project', 'Admin', 'Delivery'])
->steps([$project, $admin, $delivery]),
])->columns(1);
}
public static function form(Form $form): Form
{
$project = Wizard\Step::make('Project')->schema([ ... ]);

$admin = Wizard\Step::make('Admin')->schema([ ... ]);

$delivery = Wizard\Step::make('Addresses')->schema([
Repeater::make('Project Addresses')->schema([
Forms\Components\Select::make('type')
->options(ProjectAddressTypeEnum::class)
->required(),
Forms\Components\TextInput::make('address_line_1')
->required()
->maxLength(255),
Forms\Components\TextInput::make('address_line_2')
->maxLength(255),
Forms\Components\TextInput::make('city')
->required()
->maxLength(255),
Forms\Components\TextInput::make('postcode')
->required()
->maxLength(255),
]),
]);

return $form->schema([
Wizard::make(['Project', 'Admin', 'Delivery'])
->steps([$project, $admin, $delivery]),
])->columns(1);
}
Damien
DamienOP13mo ago
My DB structures are like so: project:
No description
Damien
DamienOP13mo ago
and project addresses:
No description
toeknee
toeknee13mo ago
Where is your ->relationship() on the repeater 😉
Damien
DamienOP13mo ago
oh dear haha let me return in just one moment
toeknee
toeknee13mo ago
I've got to get my head down in some work now, but the above link and info should get you going!
Damien
DamienOP13mo ago
all done and fixed! thanks for your help!
toeknee
toeknee13mo ago
Welcome bud!
Want results from more Discord servers?
Add your server