skip to Main Content

Making Interface class for Crud operations I need in some cases to pass custom requests(ex. CreateTagReques)t and I make it with calling class
in controller as :

public function store(Request $request)
{
    try {
        Log::info(' -1 BEFORE CreateTagRequest::');    // I see this log message
        $tag = $this->tagCrudRepository->store(
            data: $request->only('name'),
            request: new CreateTagRequest($request->all())
        );

that works, but validation method is not called actually, as :

I added log messages in app/Http/Requests/CreateTagRequest.php class :

class CreateTagRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        $request= request();              // I DO NOT SEE THIS MESSAGE :
        Log::info( '-1 CreateTagRequest $request->all()::' . print_r( $request->all(), true  ) );

and I got error:

: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'name' cannot be null (Connection: mysql, SQL: insert into `tags` (`name`) values (?))

So validation on CreateTagRequest class is not triggered. How can I trigger it ?

Problem is raised as TagCrudRepository class implements CrudInterface in app/Repositories/Interfaces/CrudInterface.php I have :

use IlluminateFoundationHttpFormRequest;

interface CrudInterface
{
    public function store(array $data, $request): Model;
...

and app/Repositories/TagCrudRepository.php :

namespace AppRepositories;

use AppHttpRequestsCreateTagRequest;

use AppRepositoriesInterfacesCrudInterface;
class TagCrudRepository implements CrudInterface
{

    public function store(array $data, $request): Tag
    {
        ...

So having 1 CrudInterface for different repository classes I need to pass different custom requests and I failed in my attempt above…

How can I do it ?

2

Answers


  1. The problem is that the CrudInterface doesn’t know anything about the CreateTagRequest. To fix this, you can add a method to the CrudInterface that will take a request and validate it. Something like this:

    public function validate(Request $request): void
    {
        $request->validate(new CreateTagRequest);
    }
    

    Then, in your TagCrudRepository, you can call this method before you store the data:

    public function store(array $data, Request $request): Tag
    {
        $this->validate($request);
    
        // ...
    }
    

    The problem is that the CrudInterface doesn’t know anything about the CreateTagRequest. To fix this, you can add a method to the CrudInterface that will take a request and validate it. Something like this:

    public function validate(Request $request): void
    {
        $request->validate(new CreateTagRequest);
    }
    

    Use code with caution. Learn more
    Then, in your TagCrudRepository, you can call this method before you store the data:

    public function store(array $data, Request $request): Tag
    {
        $this->validate($request);
    
        // ...
    }
    
    
    This will ensure that the data is validated before it is stored.
    
    Here is a complete example:
    
    app/Repositories/Interfaces/CrudInterface.php
    
    use IlluminateFoundationHttpFormRequest;
    
    interface CrudInterface
    {
        public function store(array $data, $request): Model;
    
        public function validate(Request $request): void;
    }
    
    app/Repositories/TagCrudRepository.php
    
    namespace AppRepositories;
    
    use AppHttpRequestsCreateTagRequest;
    
    use AppRepositoriesInterfacesCrudInterface;
    
    class TagCrudRepository implements CrudInterface
    {
    
        public function store(array $data, Request $request): Tag
        {
            $this->validate($request);
    
            // ...
        }
    
        public function validate(Request $request): void
        {
            $request->validate(new CreateTagRequest);
        }
    }
    
    app/Http/Requests/CreateTagRequest.php
    
    class CreateTagRequest extends FormRequest
    {
        public function authorize(): bool
        {
            return true;
        }
    
        public function rules(): array
        {
            return [
                'name' => 'required|string|max:255',
            ];
        }
    }
    

    // Source: Bard

    Login or Signup to reply.
  2. The thing I find is that on your store method you are not using formrequest.

    Public function store(CreateTagRequest $request). 
    

    You interface can only receive the validated data that came after passing from CreateTagRequest.

    After doing above mentioned changes you can change it to.

    $tag = $this->tagCrudRepository->store(data: $request>validated());
    

    On your interface you can change and only pass data parameter.

    public function store(array $data)
    

    Request is something which shouldn’t be handled on repository class or services class.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search