Im working with Laravel (11 with livewire). I have a SERVICE and i need to add some SERVICE_EXTEND fields (like wp_postmeta). SERVICE_EXTEND are generic fields with a meta_key and meta_value
Model\Service.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Class Service
*
* @property $id
* @property $father_id
* @property $category_id
* @property $customer_id
* @property $name
* @property $date
* @property $description
* @property $created_at
* @property $updated_at
*
* @property Category $category
* @property Customer $customer
* @property Service $service
* @property Service[] $services
* @property ServiceExtend[] $serviceExtends
* @property ServiceItem[] $serviceItems
* @package App
* @mixin \Illuminate\Database\Eloquent\Builder
*/
class Service extends Model
{
protected $perPage = 20;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = ['father_id', 'category_id', 'customer_id', 'name', 'date', 'description'];
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function category()
{
return $this->belongsTo(\App\Models\Category::class, 'category_id', 'id');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function customer()
{
return $this->belongsTo(\App\Models\Customer::class, 'customer_id', 'id');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function service()
{
return $this->belongsTo(\App\Models\Service::class, 'father_id', 'id');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function services()
{
return $this->hasMany(\App\Models\Service::class, 'id', 'father_id');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function serviceExtends()
{
return $this->hasMany(\App\Models\ServiceExtend::class, 'id', 'service_id');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function serviceItems()
{
return $this->hasMany(\App\Models\ServiceItem::class, 'id', 'service_id');
}
}
Forms\ServiceForm.php
<?php
namespace App\Livewire\Forms;
use App\Models\Service;
use Livewire\Form;
class ServiceForm extends Form
{
public ?Service $serviceModel;
public $father_id = '';
public $category_id = '';
public $customer_id = '';
public $name = '';
public $date = '';
public $description = '';
public function rules(): array
{
return [
'category_id' => 'required',
'customer_id' => 'required',
'name' => 'required|string',
'date' => 'required',
'description' => 'string',
];
}
public function setServiceModel(Service $serviceModel): void
{
$this->serviceModel = $serviceModel;
$this->father_id = $this->serviceModel->father_id;
$this->category_id = $this->serviceModel->category_id;
$this->customer_id = $this->serviceModel->customer_id;
$this->name = $this->serviceModel->name;
$this->date = $this->serviceModel->date;
$this->description = $this->serviceModel->description;
}
public function store(): void
{
$this->serviceModel->create($this->validate());
$this->reset();
}
public function update(): void
{
$this->serviceModel->update($this->validate());
$this->reset();
}
}
on service\form.blade.php ive added
<div>
<x-label for="matricola" :value="__('Matricola')"/>
<input type="text" name="matricola" id="matricola" wire:model.defer='matricola' class="block w-full mt-1 border-gray-300 rounded-md shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
@error('matricola')
<x-label class="mt-2" :messages="$message"/>
@enderror
</div>
on service\Create.php
<?php
namespace App\Livewire\Services;
use App\Livewire\Forms\ServiceForm;
use App\Models\Service;
use App\Models\Category;
use App\Models\Customer;
use App\Models\Item;
use Livewire\Attributes\Layout;
use Livewire\Component;
class Create extends Component
{
public ServiceForm $form;
public function mount(Service $service)
{
$this->form->setServiceModel($service);
}
public function save()
{
$this->form->store();
if ($this->form['matricola']) {
ServiceExtend::updateOrCreate(
['service_id' => $this->form->id, 'meta_key' => 'matricola'],
['meta_value' => $this->form['matricola'], 'meta_type' => null]
);
}
session()->flash('message', 'Service saved successfully.');
return $this->redirectRoute('services.index', navigate: true);
}
#[Layout('layouts.app')]
public function render()
{
$categories = Category::all()->where('type','service')->pluck('name', 'id');
$customers = Customer::all()->mapWithKeys(function ($customer) {
return [$customer->id => $customer->surname . ' ' . $customer->name];
});
$items = Item::all()->pluck('name','id');
return view('livewire.service.create', compact('categories','customers','items'));
}
}
I need to save MATRICOLA on table SERVICE_EXTEND and I dont know how.
Your syntax and setup isn't quite correct:
matricola
to your form:public $matricola = '';
<input type="text" id="matricola" wire:model='form.matricola' class="block w-full mt-1 border-gray-300 rounded-md shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
Note: name
attribute isn't necessary for Livewire, and .defer
has been removed in LW3.
That's all, actually. You need to specifically route your wire:model
to the form property using {formName}.{propertyName}
.