Sorry for this example post abit long...
My question is should i bundle validation in the action class?
blade
{{-- Modal for create or edit --}}
<form wire:submit="formAction">
// ...
</form>
component
class ListPosts extends Component
{
public PostForm $form;
public bool $showModal = false;
public string $action = '';
private function makeBlankModel(): Post
{
return Post::make();
}
// Show modal
public function create(): void
{
$this->action = 'create';
$this->form->setModel($this->makeBlankModel());
$this->showModal = true;
}
// Show modal
public function edit(Post $post): void
{
$this->action = 'edit';
$this->form->setModel($post);
$this->showModal = true;
}
// Submit the form in the modal
public function formAction(): void
{
match ($this->action) {
'edit' => $this->update(),
default => $this->store(),
};
}
// Create a new post
private function store(): void
{
$this->form->handleStore();
$this->reset(['sortField', 'sortDirection', 'action']);
$this->resetPage();
$this->showModal = false;
}
private function update(): void
{
$this->form->handleUpdate();
$this->reset(['action']);
$this->showModal = false;
}
}
form object ref: https://github.com/livewire/livewire/blob/f18f9d8205492ba9a292717fea5adde079e8aa95/src/Features/SupportFormObjects/Form.php#L34
<?php
namespace App\Livewire\Forms;
use App\Actions\CreatePost;
use App\Models\Post;
use Illuminate\Validation\ValidationException;
use Livewire\Form;
use function Livewire\invade;
class PostForm extends Form
{
public ?Post $post;
public ?string $title = null;
public ?string $body = null;
public function setModel(Post $post): void
{
$this->component->resetErrorBag();
// Model
$this->post = $post;
// Fields
$this->title = $post->title;
$this->body = $post->body;
}
public function handleStore()
{
try {
// i can't find a way in form object dependency injection, ... so
(new CreatePost)->handle($this->only(['title', 'body']));
} catch (ValidationException $e) {
invade($e->validator)->messages = $this->prefixErrorBag(invade($e->validator)->messages);
invade($e->validator)->failedRules = $this->prefixArray(invade($e->validator)->failedRules);
throw $e;
} catch (\Exception $e) {
// do something
}
$this->reset();
}
}
as you can see, there is nothing about rules and validation in the livewire
here is the action class bundle validation
<?php
declare(strict_types=1);
namespace App\Actions;
use App\Models\Post;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
class CreatePost
{
public function rules($post = null): array
{
return [
'title' => [
'required',
'string',
'min:2',
'max:255',
Rule::unique('posts')->ignore($post),
],
'body' => [
'required',
'string',
'min:2',
'max:65535',
],
];
}
public function handle(array $data): Post
{
Validator::make($data, $this->rules())
->validate();
return Post::create($data);
}
}
should i bundle validation in the action class? or any bad effect ?