Erros comuns no Laravel
Eu já vi vários erros acontecerem no Laravel que simplesmente gastariam um bom tempo do desenvolvedor que está iniciando com o framework ao tentar descobrir o motivo. Vou listar abaixo um dos mais comuns e as suas respectivas soluções para poder dar um auxílio a respeito deles.
Declarei uma rota, mas ela não é encontrada
Essa eu já vi acontecer várias vezes. O dev cria uma determinada rota no Laravel e, ao tentar acessá-la pelo navegador ou um cliente REST, simplesmente nada funciona. Sempre aparece erro 404. Ao rodar o comando php artisan route:list
ela está lá listada, da maneira como eu espero acessá-la, porém ela não funciona no navegador!
O problema que geralmente causa isso é a ordem de declaração da rota. Mais ou menos assim:
Route::get('usuario/{usuario}', 'UsuarioController@show');
Route::get('usuario/ultimos-acessos', 'UsuarioController@ultimosAcessos');
O que ocorre no caso acima é que, ao acessar a rota usuario/ultimos-acessos
, você corre grande risco de receber um 404
como resposta, devido a rota que foi definida anteriormente. Uma vez que {usuario}
se refere a um valor variável após a declaração usuario/
, o Laravel vai entender "ultimos-acessos" na url como sendo um valor para {usuario}
. O 404 ocorre geralmente porque esse valor "ultimos-acessos" ser passado como se fosse o id
do Usuário da rota.
Solução 1: Troque a ordem de declaração da rotas.
Geralmente, para resolver isso, eu costumo simplesmente trocar a ordem de declaração da rota. Assim:
Route::get('usuario/ultimos-acessos', 'UsuarioController@ultimosAcessos');
Route::get('usuario/{usuario}', 'UsuarioController@show');
Ao declarar dessa forma, o Laravel irá priorizar a rota que foi declarada primeiro na hora da busca interna.
Solução 2: Definir a expressão regular para a variável:
De acordo com a documentação do Laravel, você pode usar também o método where
para definir uma trecho de uma expressão regular para representar o valor da variável da rota.
Exemplo:
Route::get('usuario/{usuario}', function ($id) {
//
})->where('id', '[0-9]+');
Ao definir a expressão regular [0-9]+
, você fará que a rota funcione apenas quando um número for passado.
Ao rodar o db:seed
, aparece um erro, dizendo que a classe não existe
Já vi isso acontecer várias vezes. Porém, geralmente isso não costuma acontecer quando eu crio a seeder pelo comando php artisan make:seeder
. Mas tem dois casos que sempre gerava esse erro: Quando eu inventava de fazer a seeder manualmente, ou quando ela vinha de uma atualização via git pull
.
O que costuma acontecer é que, ao rodar o php artisan db:seed
, aparece que a classe não existe, mesmo ela estando na pasta database/seeder
e estando com o nome correto.
Apesar de não pesquisar o problema a fundo, eu percebi que isso ocorre por um problema no esquema Autoload do Composer.
Solução
Isso pode ser corrigido usando um composer dump
. Ao fazer isso, o Composer gerará todos os autoloads para as classes do projeto.
Agora basta a rodar o seed novamente e tudo vai funcionar.
O tinker
cria alias das minhas models, porém para alguns models não funcionam
Eu adoro usar o tinker
. E nas versões mais novas do Laravel, quando você instancia uma classe, ele costuma automaticamente resolver o namespace
da classe.
Por exemplo, se tenho o model App\Models\Usuario
e fizer um new Usuario
no tinker
, ele vai resolver o namespace
sem precisar escrever o caminho da classe inteiro. Isso é bastante útil e economiza tempo.
O problema é que as vezes parece não funcionar para models recém-criadas...
A solução é a mesma citada no caso da Seeder: rodar o composer dump
.
Se você tiver uma model (ou qualquer outra classe) cujo o namespace não esteja sendo resolvido automaticamente ao rodar o tinker, você pode simplesmente rodar composer dump
e abrir o tinker novamente.
Criei uma nova coluna na tabela, mas, ao atualizar, aquele campo não é preenchido.
Você criou uma nova coluna na sua tabela, seja com migration ou "na mão". Agora, está tentando preencher esse campo. Ao enviar pelo formulário, não funciona. Ao tentar inserir manualmente pelo php artisan tinker
, também não funciona...
O cenário é mais ou menos esse:
$usuario = Usuario::find(1);
$usuario->fill(['nova_coluna' => 'Novo valor']);
$usuario->save();
//$usuario->nova_coluna continua NULL no banco de dados
Mas o que pode ser?
Solução
Bem, você pode ter esquecido de colocar a nova coluna na propriedade $fillable
do seu Model.
Com essa propriedade, o Laravel controla quais campos serão "preenchíveis" através de métodos create
, update
ou fill
.
Faça o seguinte:
class Usuario
{
protected $fillable = [
// ... outros campos
'nova_coluna'
];
}