Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enviar ID no RULE_UPDATE #18

Closed
felipeminello opened this issue Jun 30, 2016 · 35 comments
Closed

Enviar ID no RULE_UPDATE #18

felipeminello opened this issue Jun 30, 2016 · 35 comments

Comments

@felipeminello
Copy link

Como faço para enviar o ID do meu objeto, para fazer a validação do mesmo?

Algo do tipo:

class TagValidator extends LaravelValidator
{
    protected $rules = [
        ValidatorInterface::RULE_CREATE => [
            'name' => 'required|min:3|max:50',
        ],
        ValidatorInterface::RULE_UPDATE => [
            'id'   => 'required|exists:tag',
            'name' => 'required|min:3|max:50|unique:tag,name,' . $id,
        ]
    ];
}
@brunoneve
Copy link

brunoneve commented Jul 8, 2016

@felipeminello

Digamos que você tem camada de serviço em sua aplicação.

use Illuminate\Support\Facades\Response;
use Prettus\Validator\Exceptions\ValidatorException;
use Prettus\Validator\Contracts\ValidatorInterface;

    protected $repository;
    protected $validator;

    public function __construct(SeuRepository $repository, SeuValidator $validator)
    {
        $this->repository = $repository;
        $this->validator = $validator;
    }
   public function update(array $data, $id)
    {
        try {

            $this->validator->setId($id); //funcao q set id para regra do update
            $this->validator->with($data)->passesOrFail(ValidatorInterface::RULE_UPDATE);

            return $this->repository->update($data,$id);

        } catch (ValidatorException $e){
            return Response::json([
                'error' => true,
                'message' => $e->getMessageBag()
            ],400);
        } catch (\Exception $e) {
            return Response::json([
                "error"      => true,
                "message"    => 'Ocorreu algum erro ao atualizar o registro.'
            ],400);
        }
    }

Agora em seu validator


use Prettus\Validator\Contracts\ValidatorInterface;
use Prettus\Validator\LaravelValidator;

class RoleValidator extends LaravelValidator
{
    protected $id ;
    protected $rules = [

        ValidatorInterface::RULE_CREATE => [
            'name'  => 'required|unique:roles,name',
            'display_name'  => 'required',
            'description'  => 'required'
        ],
        ValidatorInterface::RULE_UPDATE => [
            'name'  => 'required|unique:roles,name',
            'display_name'  => 'required',
            'description'  => 'required'
        ]
    ];


    public function setId($id){
        $this->id = $id;
    }

Feito isso, as regras de unique para o update do mesmo id será permitida.

Espero ter ajudado. Abraços

@edukmattos
Copy link

Desculpe a minha ignorância mas o $id não serve para excluir tal registro da verificação quando em update ?

Nao deveria ser assim:
'name' => 'required|unique:roles,name,'.$this->id.', id, deleted_at, NULL',

Mesmo fazendo dá o erro Constant expression contains invalid operations

@brunoneve
Copy link

brunoneve commented Jul 9, 2016

@ecmattos

nesse caso não, utilizando o método que passe acima, funcionará perfeitamente.

A biblioteca do prettus/validator, basta vc setar $id em sua classe de validação, ela entende que deve-se permitir o mesmo nome por exemplo, se for o mesmo id(proprio registro) quando é atualizado.

abraços

@edukmattos
Copy link

@brunoneve
Adquei o meu codigo conforme a tua sugestao.
Alterando os valores dos campos em meu formulario, concluí que está realmente bloqueando a alteracao em funcao de informações já existentes mas quando informo novos dados, surge o erro abaixo:

FatalErrorException in BaseRepository.php line 491:
Call to a member function passesOrFail() on null

Segue abaixo os meus codigos:

ClientTypeService.php

repository = $repository; $this->validator = $validator; } public function create(array $data) { $this->validator->with($data)->passesOrFail(ValidatorInterface::RULE_CREATE); return $this->repository->create($data); } public function update($id, array $data) { $this->validator->setId($id); //funcao q set id para regra do update $this->validator->with($data)->passesOrFail(ValidatorInterface::RULE_UPDATE); return $this->repository->update($data, $id); } ``` } ClientTypeValidator.php 'Código', # 'description' => 'Descrição' #]; protected $rules = [ ValidatorInterface::RULE_CREATE => [ 'code' => 'required|max:3|unique:client_types,code', 'description' => 'required|max:30|unique:client_types,description' ], ValidatorInterface::RULE_UPDATE => [ 'code' => 'required|max:3|unique:client_types,code', 'description' => 'required|max:30|unique:client_types,description' ] ]; #protected $messages = [ # 'required' => ':attribute >> Preenchimento obrigatório.', # 'max' => ':attribute >> MÁXIMO :max caracteres.', # 'unique' => ':attribute >> Indisponível.' #]; public function setId($id) { $this->id = $id; } ``` }

@edukmattos
Copy link

@brunoneve

O meu controller (ClientTypeController.php)

public function update(Request $request, $id)
{
try
{
$input = $request->all();
$clientType = $this->service->update($id, $input);

        $response = [
            'message' => 'Tipo de Cliente alterado com sucesso !',
            'data'    => $clientType->toArray(),
        ];

        if ($request->wantsJson()) {

            return response()->json($response);
        }

        #return redirect()->back()->with('message', $response['message']);
        return redirect()->route('clientTypes.index');
    } 
    catch (ValidatorException $e) 
    {
        if ($request->wantsJson()) 
        {
            return response()->json([
                'error'   => true,
                'message' => $e->getMessageBag()
            ]);
        }

        return redirect()->back()->withErrors($e->getMessageBag())->withInput();
    }
}

@brunoneve
Copy link

Esse erro ocorre, durante o create ou update ?

@edukmattos
Copy link

@brunoneve
Update

@brunoneve
Copy link

brunoneve commented Jul 9, 2016

Tenta assim

Controller

    public function update(Request $request, $id)
    {
            $input = $request->all();
            $clientType = $this->service->update($id, $input);

            $response = [
                'message' => 'Tipo de Cliente alterado com sucesso !',
                'data'    => $clientType
            ];

            if ($request->wantsJson()) {

                return response()->json($response);
            }

            return redirect()->route('clientTypes.index');
    }

Service


namespace L52\Services;

use L52\Repositories\ClientTypeRepository;
use L52\Validators\ClientTypeValidator;
use Prettus\Validator\Contracts\ValidatorInterface;
use Illuminate\Support\Facades\Response;
use Prettus\Validator\Exceptions\ValidatorException;

class ClientTypeService
{
    protected $repository;
    protected $validator;

    public function __construct(ClientTypeRepository $repository, ClientTypeValidator $validator)
    {
        $this->repository = $repository;
        $this->validator = $validator;
    }

    public function create(array $data)
    {
        $this->validator->with($data)->passesOrFail(ValidatorInterface::RULE_CREATE);
        return $this->repository->create($data);
    }

    public function update($id, array $data)
    {

            try {
                $this->validator->setId($id);
                $this->validator->with($data)->passesOrFail(ValidatorInterface::RULE_UPDATE);

                return $this->repository->update($data,$id);

            } catch (ValidatorException $e){
                return Response::json([
                    'error' => true,
                    'message' => $e->getMessageBag()
                ],400);
            } catch (\Exception $e) {
                return Response::json([
                    "error"      => true,
                    "message"    => 'Ocorreu algum erro ao atualizar o registro.'
                ],400);
            }


    }
}

Fiz algumas alterações, veja se resolve.

@edukmattos
Copy link

@brunoneve

Oi!

Ainda aparece o erro FatalErrorException in BaseRepository.php line 491:
Call to a member function passesOrFail() on null

Meu controlador:
namespace L52\Http\Controllers;

use Illuminate\Http\Request;

#use L52\Http\Requests;
use Illuminate\Support\Facades\Response;
use Prettus\Validator\Exceptions\ValidatorException;
use L52\Repositories\ClientTypeRepository;
use L52\Services\ClientTypeService;

@edukmattos
Copy link

@brunoneve

A acao update deixei iagual ao que tu me enviaste:

public function update(Request $request, $id)
{
try
{
$input = $request->all();
$clientType = $this->service->update($id, $input);

        $response = [
            'message' => 'Tipo de Cliente alterado com sucesso !',
            'data'    => $clientType,
        ];
        return redirect()->route('clientTypes.index');
    }
    catch (ValidatorException $e)
    {
        return Response::json([
            'error'   => true,
            'message' => $e->getMessageBag()
        ]);
    }
}

@brunoneve
Copy link

@ecmattos editei meu poste, olhe novamente, tirei o validatorException do controller e joguei no service.

@edukmattos
Copy link

@brunoneve

Segue abaixo uma outra sugestao que recebi de um forum mas não consegui também e nao achei muito legal. O que achas ?

Olá Eduardo, no seu caso, precisaremos do $request para pegar o id que vem da rota, ou pode vim do formulário também.

Então podemos adicionar um método construtor no validator e passar o request.

Exemplo:

public function __construct(Factory $validator, Request $request)
{
parent::__construct($validator);
$this->rules = [
'name' => 'required|max:255'.$request->route('id'),
'responsible' => 'required|max:255',
'email' => 'required|email',
'phone' => 'required',
'address' => 'required'
];
}

@edukmattos
Copy link

@brunoneve

Agora a mensagem mudou para:

ValidatorException in AbstractValidator.php line 109:

O meu controller está assim:

namespace L52\Http\Controllers;

use Illuminate\Http\Request;

#use L52\Http\Requests;
use Illuminate\Support\Facades\Response;
#use Prettus\Validator\Exceptions\ValidatorException;
use L52\Repositories\ClientTypeRepository;
use L52\Services\ClientTypeService;

No meu service, assim:

@edukmattos
Copy link

@brunoneve
Em outras aplicacçoes que desenvolvi no Laravel sem utilizar a metodologia do Repository Pattern, eu utilizava os Requests (tipo ClientTypeRequest.php) para fazer as valizações e funcionava legal.

@edukmattos
Copy link

@brunoneve
Se quiseres posso disponibilizar a aplicacao num repositorio para que possas ver ?

@brunoneve
Copy link

brunoneve commented Jul 9, 2016

Seu prettus está atualizado ?

eu uso "prettus/l5-repository": "^2.5",

Ok, mande o link do repository

@edukmattos
Copy link

@brunoneve
"prettus/l5-repository": "^2.6",

@brunoneve
Copy link

@ecmattos ok, quando subir para o git, me avise. Meu skype bnneves

@edukmattos
Copy link

@brunoneve

https://github.com/ecmattos/L52.git

Vá em menu Administracao > Clientes > Tipos

usuario: [email protected]
senha: 123456

@edukmattos
Copy link

@brunoneve
php artisan migrate:refresh --seed

@edukmattos
Copy link

rsrsrs

@brunoneve
Copy link

Mandei PR la, depois olha, fiz os testes e estão funcionando agora.

So precisa adaptar para exibir os erros em suas views.

Abraços

@edukmattos
Copy link

O que é PR ?
Desculpe a minha ignorancia !

@brunoneve
Copy link

brunoneve commented Jul 9, 2016

@ecmattos Pull Request,

veja (https://github.com/ecmattos/L52/pulls)

@edukmattos
Copy link

ok estou vendo agora mesmo.

@brunoneve
Copy link

Basta aceitar e dar um merge, q vai atualizar pra vc, depois faz um git pull em seu pc.

@edukmattos
Copy link

@brunoneve

Oi !
Dei o merge e e fiz um git clone ao inves do git pull (claro que antes renomeei a minha pasta).

Mas ao alterar o registro forcando a uma duplicacao de informacao, dá o erro:

ValidatorException in AbstractValidator.php line 109:
in AbstractValidator.php line 109
at AbstractValidator->passesOrFail('update') in ClientTypeService.php line 30
at ClientTypeService->update('2', array('_method' => 'PUT', '_token' => 'Jr9IbLyWhhx9hkAfPPoDgwH5YTOY8VSaiWiUvPTW', 'code' => 'PJ', 'description' => 'PESSOA FISICA')) in ClientTypesController.php line 148
at ClientTypesController->update(object(Request), '2')
at call_user_func_array(array(object(ClientTypesController), 'update'), array(object(Request), 'id' => '2')) in compiled.php line 9419
at Controller->callAction('update', array(object(Request), 'id' => '2')) in compiled.php line 9481
at ControllerDispatcher->call(object(ClientTypesController), object(Route), 'update') in compiled.php line 9461
at ControllerDispatcher->Illuminate\Routing{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 52
at Pipeline->Illuminate\Routing{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in compiled.php line 9938
at Pipeline->then(object(Closure)) in compiled.php line 9462
at ControllerDispatcher->callWithinStack(object(ClientTypesController), object(Route), object(Request), 'update') in compiled.php line 9449
at ControllerDispatcher->dispatch(object(Route), object(Request), 'L52\Http\Controllers\ClientTypesController', 'update') in compiled.php line 8517
at Route->runController(object(Request)) in compiled.php line 8504

@edukmattos
Copy link

tá quase !

@edukmattos
Copy link

@brunoneve

Tem alguma coisa a ver com Custom validation message not coming #10 ?

@edukmattos
Copy link

@brunoneve
Adicionei no controlador do ClientTypeService.php

use Illuminate\Support\Facades\Response;
use Prettus\Validator\Exceptions\ValidatorException;

Só que agora nao aparece mais as mensagens de erros, submete os dados duplicados mas realiza as alteracoes.

@edukmattos
Copy link

@brunoneve
Corrigindo...
Só que agora nao aparece mais as mensagens de erros, submete os dados duplicados mas não realiza as alteracoes (o que está correto).

@edukmattos
Copy link

@brunoneve
Nao estou conseguindo com que as mensagens de erros do ClientTypeValidator.php apareçam.
Poderia me ajudar ?

Segue o meu repositorio: https://github.com/ecmattos/L52.git

@felipeminello
Copy link
Author

@brunoneve Obrigado !!

Solucionou o problema

@ghost
Copy link

ghost commented Oct 4, 2016

Hi,

I would be grateful if someone share the solution as I am having the same problem.

Thanks

@brunoneve
Copy link

You need to say what id should be allowed in the update.

Example:

            $this->validator->setId($id);
            $this->validator->with($data)->passesOrFail(ValidatorInterface::RULE_UPDATE);

Your validator

protected $rules = [

    ValidatorInterface::RULE_CREATE => [
        'name'  => 'required|unique:roles,name',
        'display_name'  => 'required',
        'description'  => 'required'
    ],
    ValidatorInterface::RULE_UPDATE => [
        'name'  => 'required|unique:roles,name',
        'display_name'  => 'required',
        'description'  => 'required'
    ]
];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants