I have a Laravel 10 project going where I'm learning to use Inertia and Vue 3.
Using the Breeze starter pack, I have created a new Model, Address, and I'm starting by
defining the relationship between Users and Addresses, but Addresses will eventually
have relationships to other models as well.
A user can have 1 address, a one-to-one polymorphic relationship defined as such:
public function address(): MorphOne
{
return $this->morphOne(Address::class, 'addressable');
}
And of course, the addressable() relationship is defined on the address as well. An Address record can only belong to one other model, so:
public function addressable(): MorphTo
{
return $this->morphTo();
}
Given that I'm using Breeze, I decided that I would create an AddressForm vue component that could be used wherever I might need to create or edit an address. I'm including it in js/Pages/Profile/Edit.vue :
<script setup>
import { Head } from '@inertiajs/vue3';
import AddressForm from '@/Components/AddressForm.vue';
...
<div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow sm:rounded-lg">
<AddressForm class="max-w-xl" :address="$page.props.address" />
</div>
I'm passing the Address model as a prop from ProfileController::edit()
The AddressForm component looks like this:
<script setup>
import { useForm } from '@inertiajs/vue3';
import InputError from '@/Components/InputError.vue';
import InputLabel from '@/Components/InputLabel.vue';
import PrimaryButton from '@/Components/PrimaryButton.vue';
import TextInput from '@/Components/TextInput.vue';
let props = defineProps({
address: {
type: Object,
},
});
const form = useForm({
description: props.address.description,
attention: props.address.attention,
street1: props.address.street_1,
street2: props.address.street_2,
city: props.address.city,
state: props.address.state,
postalCode: props.address.postal_code,
countryCode: props.address.country_code,
});
const submit = () => {
form.post(route('address.store'), {
onFinish: () => form.reset(),
});
};
</script>
<template>
<section class="space-y-6">
<header>
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">Address</h2>
</header>
<form @submit.prevent="submit">
<div>
<InputLabel for="description"
value="Description" />
<TextInput id="description"
type="text"
class="block w-full mt-1"
v-model="form.description"
required />
<InputError class="mt-2"
:message="form.errors.description" />
</div>
<div>
<InputLabel for="attention"
value="Attention" />
<TextInput id="attention"
type="text"
class="block w-full mt-1"
v-model="form.attention"
required />
<InputError class="mt-2"
:message="form.errors.attention" />
</div>
<div>
<InputLabel for="street1"
value="Street Address" />
<TextInput id="street1"
type="text"
class="block w-full mt-1"
v-model="form.street1"
required />
<InputError class="mt-2"
:message="form.errors.street1" />
</div>
<div>
<InputLabel for="street2"
value="Street Address: Line 2" />
<TextInput id="street2"
type="text"
class="block w-full mt-1"
v-model="form.street2" />
<InputError class="mt-2"
:message="form.errors.street2" />
</div>
<div>
<InputLabel for="city"
value="City" />
<TextInput id="city"
type="text"
class="block w-full mt-1"
v-model="form.city"
required />
<InputError class="mt-2"
:message="form.errors.city" />
</div>
<div>
<InputLabel for="state"
value="State" />
<TextInput id="state"
type="text"
class="block w-full mt-1"
v-model="form.state" />
<InputError class="mt-2"
:message="form.errors.state" />
</div>
<div>
<InputLabel for="postalCode"
value="Postal Code" />
<TextInput id="postalCode"
type="text"
class="block w-full mt-1"
v-model="form.postalCode"
required />
<InputError class="mt-2"
:message="form.errors.postalCode" />
</div>
<div>
<InputLabel for="countryCode"
value="Country Code" />
<TextInput id="v"
type="text"
class="block w-full mt-1"
v-model="form.countryCode"
required />
<InputError class="mt-2"
:message="form.errors.countryCode" />
</div>
<div class="flex justify-end mt-4">
<PrimaryButton class="ml-4"
:class="{ 'opacity-25': form.processing }"
:disabled="form.processing">
Save
</PrimaryButton>
</div>
</form>
</section>
</template>
So far, so good. My form as the data I've seeded for the authenticated user's address.
Now, I want to be able to edit that data and submit the form.
I have an AddressController::store method that is a work in progress, but my expectation is that I'll have to be able to pass the address_id to update an existing address, and addressable_type and addressable_id when I'm creating a new address. How can I submit this with my form(s) so that the AddressController methods can do their thing?