Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Bom dia,
iniciei os estudos voltados ao Laravel.
Por enquanto está tudo muito lindo, porém me surgiu uma dúvida, onde por exemplo:
Exemplo:
Vamos imaginar um grupo de pessoas, onde cada grupo possui um líder
-
Líder
-
Pessoas
-
Cargos no grupo
Seguindo uma hierarquia, onde o líder daquele grupo, pode adicionar N pessoas em X grupos.
Até ai tudo bem, seria apenas usar:
<?php
class HomeController
{
public function add($pGrupo, $pPessoa) {
$grupo = new Grupo();
$grupo->grupoID = $pGrupo;
$grupo->pessoaID = $pPessoa;
$grupo->liderID = 5; // não sei se poder usar session, enfim...
$grupo->save();
}
}
O problema é que eu preciso verificar se o líder realmente é quem ele diz ser (líder)
antes de poder cadastrar ao banco de dados.
Teria problemas fazer isso antes de adicionar?
<?php public function add($pGrupo, $pPessoa) {
$grupo = new Grupo();
$lider = Lider::where('id', '=', '5')->get();
if (count($lider) > 0)
{
$grupo->grupoID = $pGrupo;
$grupo->pessoaID = $pPessoa;
$grupo->liderID = 5; // não sei se poder usar session, enfim...
$grupo->save();
}
}
}
Caso tenha, qual seria a forma correta de se fazer isso?
Visto que em caso real eu posso ter que checar muitas outras coisas antes...
Obrigado!Não sou entendido de Laravel e também preciso lhe dizer que entre o Laravel 5.1, 5.2, 5.3 e 5.4 as coisas mudam bastante, não tenho certeza se o ORM deles muda muito, pelo doc parece estar ainda bem compatível, então irei citar me baseando no 5.4 (pois você não citou a versão).
Não há problema algum em fazer isto olhando do ponto de vista:
Lider::where('id', '=', '5')->get();
No entanto eu pessoalmente acho bastante desnecessário pegar o resultado todo e depois usar o `count($resultado)`, o proprio Eloquent tem um método chamado `::cout()`, poderia fazer assim:
public function add($pGrupo, $pPessoa)
{
$idDoLider = 5; // talvez a sessão, o que me parece apropriado
$grupo = new Grupo();
$lider = Lider::where('id', '=', $idDoLider)->count();
if (count($lider)) {
$grupo->grupoID = $pGrupo;
$grupo->pessoaID = $pPessoa;
$grupo->liderID = $idDoLider;
$grupo->save();
}
}
Também vale notar que poderia usar, além do método `save`, os métodos **firstOrCreate** e **firstOrNew.**
**- firstOrCreate** a irá tentar retornar os dados do banco do primeiro item localizado, se não encontrar tenta persistir no banco e retornará o Model, conforme exemplo da doc:
$flight = App\Flight::firstOrCreate(['name' => 'Flight 10']);
**- firstOrNew** irá tentar retornar os dados do banco do primeiro item localizado, se não encontrar irá retornar um Model, mas não irá persistir no banco, o que pode ser interessante se antes de usar o "save" você quiser ajustar algo nos dados, conforme exemplo da doc:
$flight = App\Flight::firstOrNew(['name' => 'Flight 10']);
Outro detalhe é que o "get" retorna um objeto como array (ou algo "iterável"), no caso se fizer a consulta no where por um ID principal é porque pretende apenas trazer os dados de uma única linha, se usar "get" como citei terá que usar o for, foreach, etc, mas se algo invés disto pode usar o "->first();" que irá retornar o Model diretamente, seria algo como:
Pessoa::where('id', 98)->first();
Além do first, firstOrCreate e firstOrNew existe um método muito útil, imagine que quer exibir uma página de perfil de um cliente ou usuário, se ele não existir você provavelmente iria colocar uma página de erro e talvez usar um código HTTP, o Eloquent tem um método chamado `->firstOrFail();`, ou seja se não encontrar o que procura ele irá emitir uma exception chamada **"Illuminate\Database\Eloquent\ModelNotFoundException" **o que vai emitir um código 404 para o cliente (navegador) e se tiver páginas de erro customizada no Laravel poderá direcionar.
>
Citar
Nota: Creio que o sinal de igual seja redundante where('id', '=', $idDoLider), ao menos no Laravel 5.4, creio que possa fazer assim diretamente where('id', $idDoLider), só será necessário se for usar <>, >, <, etc.
>
2 horas atrás, brcontainer disse:
Não sou entendido de Laravel e também preciso lhe dizer que entre o Laravel 5.1, 5.2, 5.3 e 5.4 as coisas mudam bastante, não tenho certeza se o ORM deles muda muito, pelo doc parece estar ainda bem compatível, então irei citar me baseando no 5.4 (pois você não citou a versão).
Não há problema algum em fazer isto olhando do ponto de vista:
Lider::where('id', '=', '5')->get();
No entanto eu pessoalmente acho bastante desnecessário pegar o resultado todo e depois usar o `count($resultado)`, o proprio Eloquent tem um método chamado `::cout()`, poderia fazer assim:
public function add($pGrupo, $pPessoa)
{
$idDoLider = 5; // talvez a sessão, o que me parece apropriado
$grupo = new Grupo();
$lider = Lider::where('id', '=', $idDoLider)->count();
if (count($lider)) {
$grupo->grupoID = $pGrupo;
$grupo->pessoaID = $pPessoa;
$grupo->liderID = $idDoLider;
$grupo->save();
}
}
Também vale notar que poderia usar, além do método `save`, os métodos **firstOrCreate** e **firstOrNew.**
**- firstOrCreate** a irá tentar retornar os dados do banco do primeiro item localizado, se não encontrar tenta persistir no banco e retornará o Model, conforme exemplo da doc:
$flight = App\Flight::firstOrCreate(['name' => 'Flight 10']);
**- firstOrNew** irá tentar retornar os dados do banco do primeiro item localizado, se não encontrar irá retornar um Model, mas não irá persistir no banco, o que pode ser interessante se antes de usar o "save" você quiser ajustar algo nos dados, conforme exemplo da doc:
$flight = App\Flight::firstOrNew(['name' => 'Flight 10']);
Outro detalhe é que o "get" retorna um objeto como array (ou algo "iterável"), no caso se fizer a consulta no where por um ID principal é porque pretende apenas trazer os dados de uma única linha, se usar "get" como citei terá que usar o for, foreach, etc, mas se algo invés disto pode usar o "->first();" que irá retornar o Model diretamente, seria algo como:
Pessoa::where('id', 98)->first();
Além do first, firstOrCreate e firstOrNew existe um método muito útil, imagine que quer exibir uma página de perfil de um cliente ou usuário, se ele não existir você provavelmente iria colocar uma página de erro e talvez usar um código HTTP, o Eloquent tem um método chamado `->firstOrFail();`, ou seja se não encontrar o que procura ele irá emitir uma exception chamada **"Illuminate\Database\Eloquent\ModelNotFoundException" **o que vai emitir um código 404 para o cliente (navegador) e se tiver páginas de erro customizada no Laravel poderá direcionar.
Muito obrigado pelo seu comentário. Supriu algumas dúvidas minhas sobre.
Porém o que realmente me preocupa é que eu preciso fazer consulta para verificar X coisa.
Digamos por exemplo um sistema escolar, onde o professor tem permissão para dar aula na TURMA 200 sob a matéria Inglês.
O mesmo quer adicionar a nota dos alunos, porém antes de eu permitir o envio eu precisaria verificar se aquele professor realmente tem permissão sob aquela turma/matéria, verificar se o aluno consta naquela turma e se está matriculado.
Acho que deu para expressar melhor, ou seja olha quantas verificações eu teria que fazer.
É normal eu fazer isso tudo no mesmo método ou tem alguma outra forma de se fazer isso com laravel?Entendi, o que você quer é fazer o relacionamento entre as tabelas, digamos você tem como mostrar como estas são? Talvez o CREATE TABLE. Se não tiver as tabelas recomendo que leia isto primeiro [Qual é a diferença entre INNER JOIN e OUTER JOIN?](http://pt.stackoverflow.com/a/6448/3635) Entender a diferença é relativo para o caso especifico creio que vá necessitar apenas do innerjoin.
Ainda sim @jamesbond, se você não tiver as tabelas ou algo assim amanhã (hoje) tento preparar um exemplo pra ti e mostro também como criar o querybuilder pelo EloquentObrigado novamente.
Mas eu sei como elaborar a query (não usando o facade do laravel, estou ainda lendo a documentação para obter mais info sobre), digo em questão de arquitetura.
É correto fazer essas verificações todas, verificar se existe, etc.
Tudo naquele método que vai cadastrar?
@jamesbond entenda que correto é algo extremamente relativo e que pode ser interpretado de inumeras maneiras por pessoas diferentes, se você tem o conhecimento de MySQL e de JOIN, então o que lhe resta é adaptar para o Eloquent.
Como eu disse sem saber a estrutura da tabela não posso lhe indicar o *caminho mais adequado*, as vezes um SELECT simples na tabela GRUPO resolve, as vezes terá que fazer um relacionamento entre GRUPO e LIDER.
Agora a resposta curta é, sim tem que checar, de preferencia poderia até isto para um **[Middleware](https://laravel.com/docs/5.4/middleware)**(mas não vou falar disto agora porque é algo bem mais complexo), qreio que checar se o GRUPO pertence ao LIDER já seria o suficiente (estou presumindo), um pseudo-código:
$idDoLider = 5;//Id do lider na sessão
//Checa se esta conta de lider existe e esta ativada (supondo que possa desativar por segurança em caso de demissão)
if (!Lider::where('id', $idDoLider)->where('ativo', 1)->count()) {
return 'Este grupo não pertence a ti ou não existe';
}
//Checa se este grupo pertence ao lider logado no momento
if (!Grupo::where('id', $idGrupoQueIraCadastrarPesso)->where('idLider', $idDoLider)->count()) {
return 'Este grupo não pertence a ti ou não existe';
}>
26 minutos atrás, brcontainer disse:
@jamesbond entenda que correto é algo extremamente relativo e que pode ser.....
Esse foi um exemplo simples e curto. Porém no atual projeto é mais ou menos o que eu passei no segundo exemplo sob a escola.
Onde seria por exemplo a seguinte estrutura de tabelas:
-
Professor
-
Estudante
-
ConfProfessor (TURMA + CLASSE)
-
Chamada
Vamos elaborar um code aqui
<?php
namespace App\Http\Controllers;
use Request;
use App\Professor;
use App\Estudante;
use App\ConfProf;
use App\ConfClasse;
use App\Turma;
use App\Disciplina;
class ChamadaController extends Controller
{
public function adicionar()
{
// obtém o valor inserido no input turma
$turma = Request::input("turma");
// obtém o valor inserido no input disciplina
$disciplina = Request::input("disciplina");
// obtém o valor inserido no input estudante
$estudante = Request::input("estudante");
// obtém o id do professor logado
$professor = Request::session()->get("usuarioID", "");
// não sei ainda a forma de se fazer direto igual você expecificou
$consultaConfProf = ConfProf::where("professor", $professor)->where("disciplina", $disciplina)->where("turma", $turma)->get();
// consulta a turma de acordo com a mesma selecionada
$consultaTurma = Turma::where("id", $turma)->get();
// consulta a disciplina de acordo com a mesma selecionada
$consultaDisc = Disciplina::where("id", $disciplina)->get();
// consulta o estudante de acordo com o registro de matricula
$consultaEstu = Estudante::where("rm", $estudante)->get();
// consulta no banco de dados
// se existe aquela disciplina
// sob a classe selecionada
$consultaConfClasse = ConfClasse::where("classeID", $turma)->where("disciplina", $disciplina)->get();
// verifica se o professor está
// apto para adicionar sob
// aquela classe/disciplina
if (count($consultaConf))
{
// verifica se a turma e a disciplina
// existem
if ((count($consultaTurma)) && (count($consultaDisc)))
{
if (count($consultaConfClasse))
{
// verifica se o estudante
// existe
if (count($consultaEstu))
{
// verifica se o estudante
// está matrículado e estudando
// naquela turma
if (($consultaEstu->situacao == 5) && ($consultaEstu->turma == $turma))
{
// cadastra a chamada
}
}
}
}
}
}
}
Deixei comentado para você analisar de forma mais coerente.
Essa quantidade de if me incomoda.
O que vou precisar fazer é semelhante isso, gostaria de saber se existe uma outra forma de fazer o que foi feito nesse código.
Aceito dicas para melhorar tudo que está ai, faz um dia que iniciei os estudos em laravel. Obrigado!Estou um pouco sem tempo para analisar detalhe por detalhe, mas a primeira coisa que eu faria se fosse você seria trocar todos os 'count' por '->count()' diretamente, sem precisar ficar usando if, no geral várias ifs no seu código são desnecessárias e poderia estar todas em um mesmo.
Prometo que quando estiver dia (e eu estiver um pouco mais acordado) vejo se consigo revisar teu código de maneira que fique mais limpo e assim você pode observar e até pensar em maneiras outras maneiras de reduzir.
Boa noite.
>
6 minutos atrás, brcontainer disse:
Estou um pouco sem tempo para analisar detalhe por detalhe, mas a primeira coisa que eu faria se fosse você seria trocar todos os 'count' por '->count()' diretamente, sem precisar ficar usando if, no geral várias ifs no seu código são desnecessárias e poderia estar todas em um mesmo.
Prometo que quando estiver dia (e eu estiver um pouco mais acordado) vejo se consigo revisar teu código de maneira que fique mais limpo e assim você pode observar e até pensar em maneiras outras maneiras de reduzir.
Boa noite.
Obrigado. O que me mata é não estar acostumado com o mesmo.
De outras formas talvez eu tentaria usar chain of responsibility para percorrer esse tanto de if.
Mas por fim, muito obrigado.
Até já, boa noite.
up