Dúvida ao realizar operações que inserem ou alteram dados no banco
[Finalizado Pelo Aluno]
Boa noite.
Carlos, eu uso no meu dia a dia no trabalho o framework CakePHP.
Logo nos meus primeiros contatos com Laravel uma coisa me chamadou muito a atenção nas operações que envolvem inserir e alterar dados no banco. Tem uma pequena diferença que achava estranho da parte do Laravel comparando os exemplos na documentação de ambos os frameworks.
No CakePHP na forma mais comum seria passar um Entity para um repositorio fazer as operações de insert e update usando o metodo save(). Algo com como $this->Users->save($user);
O Laravel tem as formas dele que vc conhece bem.
Mas o que me chama atenção é que no Cake sempre escrevia o método de salvar dentro de um if para exibir uma mensagem de sucesso caso a operação fosse realizada com sucesso e redirecionar o usuário ou retornar a página anterior com alguma informação do erro. Algo como isso no cake:
if ($this->Articles->save($article)) { $this->Flash->success(__('Your article has been saved.')); return $this->redirect(['action' => 'index']); }
$this->Flash->error(__('Unable to add your article.'));
Em contrapartida na documentação do Laravel os exemplos sempre salvam diretamente o Model ou pelo método save ou create, sem esse if para tratar o sucesso ou erro da operação.
Eu sempre achei isso meio falho na parte da documentação. Perguntava: e se der erro?
Mas agora me veio uma coisa na cabeça que acho que entendi o porque do Laravel salvar diretamente sem esperar que possa acontecer um erro ao salvar o model no banco.
Acho que tem haver com a arquitetura dos Frameworks. O Cake tem dois estágios de validação, o primeiro seria ao contruir as entidades (validators) que validam por exemplo o formato dos dados, se poder ser vazio, nulo, etc. E o segundo estágio são as build rules, que a documentação descreve como regras de negócio que não são regra de formatos de dados, mas algo como restriçoes, ex: Um usuário só pode ter um comentário em um post, então eu crio essa regra (build rule) e sempre que o usuário form comentar um post ao savar o comentário se o usuário já tem um comentário no post então esse novo comentário não será salvo logo retornará um erro.
Resumindo, então se minha compreensão estiver certa, o Laravel não tem esse IF para verificar se salvou/atualizou o model porque ele simplesmete vai salvar, pois os dados já foram validados no metodo validate do request ou em um Request, logo ele não vai me retornar nehum erro quanto a operação de salvar/atualizar porque já validei os dados antes de chegar no banco.
Por outro lado o cake tem essas regras de validação antes de salvar no banco, logo pode salvar ou dar erro e preciso desse if para fazer o tratamento.
A unica chance de dar erro ao persistir informações no banco usando Laravel seria se não validasse corretamente meus dados e deixar passar um string maior que 255 caracteres e coisas semelhantes ou alguma falha de infra, como erro de conexão com o banco bem na hora de salvar.
Seria isso mesmo o motivo da diferença?
Eu achava que o Laravel era irresponsável ao mandar salvar diretamente sem tratar algum possivel erro. kkkkkkkk.
Mas agora olhando desse ponto de vista começo acreditar que é apenas uma questão de arquitetura.
Desculpe o textão, mas isso sempre me deixou inquieto.
Olá, Rafael!
Como vai?
Excelente ponto que você levantou.
Vamos por partes:
1) Eu sempre achei isso meio falho na parte da documentação. Perguntava: e se der erro?
Neste caso, é um erro, é interessante deixar a exception ser lançada (gerar logs e etc), porque erro é erro, erro é grave, especialmente se foi algo relacionado a banco de dados.
Mas, você pode fazer a operação dentro de um try catch e exibir uma mensagem "amistosa" para o usuário, mesmo que seja um problema grave (como por exemplo conexão com o banco errada ou algo do tipo).
try {
// insert no banco
} catch (Exception $e) {
return back()->with('error', 'Falha ao inserir');
}
2) Sobre as validações do Laravel:
Sim, existem N tipos de validações, inclusive para validar se algo já foi persistido ou não no banco "unique:nome_tabela", é possível ainda criar excessões para validações únicas no update
https://github.com/especializati/curso-de-laravel-10/blob/main/app/Http/Requests/StoreUpdateSupport.php#L40
O Laravel tem o Eloquent ORM, que utiliza o active record, logo o model é um repositório, o próprio objeto do model permite persistir/alterar o registro do banco, por isso os dados que chegam no model, já precisam ter sido previamente validados (em outra camada). É um pouco complexo explicar isso aqui em um texto a diferença entre active record vs data mapper, mas vale dá uma pesquisada depois.
---
Não sei se fui claro em todas as suas dúvidas amigo, mas se tiver qualquer outra dúvida, por favor, escreva aqui que terei o maior prazer do mundo em te responder.
Boa noite Carlos.
Sim eu entendo o conceito de usar o Try catch que vc mencionou e é bem útil.
Também estou ciente da do que é o Active Record e data mapper (não tão a fundo talvez, mas entendo), e que o Laravel usa Active Record.
Eu sinceramente prefiro ter separado o Repository do modelo/entity. Para concentrar tudo de código que envolve operações de banco no repository e tratamento de dados na entity. Semelhante ao que o Cake faz.
Obrigado por esclarecer essas dúvidas.
Precisa estar logado para conseguir responder a este ticket!
Clique Aqui Para Entrar!