[PROMOÇÃO] Assine com + 30% de desconto ANUAL MENSAL (últimas horas)
Rafael Lannes
Criador Rafael Lannes 11/10/2022

Boa noite

Tenho uma situação que estou com dificuldade de encontrar a melhor maneira de implementar....

Então, o banco não é 100% uuid.... Tá no escopo do curso anterior, o LaraFood!
A minha tabela de Tenant é os seguintes campos: id, descrição, uuid
____
 
Nos restantes das tabelas eu tenho o tenant_id como chave estrangeira, por exemplo a tabela Categoria tem os campos: id, descrição, tenant_id
 
Quando eu faço a requisição para a API, eu faço parecido dessa maneira
https://academy.especializati.com.br/aula/api-laravel-recuperar-todas-categorias-p2
 
Usando o hash(tenant_id) como parâmetro obrigatório via Form Request, igual na aula.
 
O que eu gostaria de fazer é exatamente isso, só que filtrando as categorias somente do Tenant vinculado ao hash(sem ficar passando o tenant_id em toda query), do mesmo modo que foi feito na parte de Admin, com aquele Trait usando o Escopo (sendo que meu painel é um projeto a parte do projeto da API)
 
Obrigado desde já!

 

Manager Carlos Ferreira 11/10/2022

Olá, Rafael!
Tudo bem?

Se você filtrar usando um model, que usa a trait de tenant, vai automaticamente já aplicar o tenant_id;

Também é possível desabilitar o tenant default do model:
https://laravel.com/docs/9.x/eloquent#removing-global-scopes

Aí dessa forma você pode usar mesmo um scope local, e aplicar conforme o tenant_id da request:
https://laravel.com/docs/9.x/eloquent#local-scopeshttps://laravel.com/docs/9.x/eloquent#local-scopes
public function scopeTenant($query)
{
    return $query->where('tenant_id', request()->get('tenant_id'));
}

Pegou a ideia? É isso mesmo que precisa?

Carlos Ferreira
Criador Rafael Lannes 11/10/2022

É exatamente isso.... até uma parte eu consigo avançar,

A minha questão é como eu consigo recuperar o valor do form request(uuid do tenant) dentro do escopo, igual nessa imagem

https://imgur.com/a/4i9PZJf 

 

Tentei colocar direto aqui mas não foi.....

 

Nesse caso eu teria que ter o valor do '$request->uuid' para conseguir filtrar pelo tenant

Rafael Lannes
Criador Rafael Lannes 11/10/2022

https://i.imgur.com/yQIBguF.png

Rafael Lannes
Manager Carlos Ferreira 11/10/2022

E a ideia de usar um escopo local (local scope), acha que te atende?
https://laravel.com/docs/9.x/eloquent#local-scopeshttps://laravel.com/docs/9.x/eloquent#local-scopes
public function scopeTenant($query)
{
    return $query->where('uuid', request()->get('tenant_id'));
}

Aí sua query ficaria:
$result = NomeModel::tenant()->get();

Carlos Ferreira
Criador Rafael Lannes 11/10/2022

Atenderia sim, mas a questão é que praticamente todos os modelos vão seguir essa regra de filtrar pelo tenant

Nesse caso, voce acha que seria a melhor solução?

Rafael Lannes
Manager Carlos Ferreira 11/10/2022

Se todos os models irão aderir, melhor scope global mesmo.

E se eventualmente, algum model não precisar, basta desabilitar: https://laravel.com/docs/9.x/eloquent#removing-global-scopes

Carlos Ferreira
Criador Rafael Lannes 11/10/2022

Beleza!

Mas como eu faço para conseguir acessar o request nesse arquivo?

 

https://i.imgur.com/yQIBguF.png

Rafael Lannes
Criador Rafael Lannes 11/10/2022

Eu poderia injetar o Request nessa função Apply?

Rafael Lannes
Manager Carlos Ferreira 11/10/2022

Usa o helper: request()->get('uuid')

Carlos Ferreira
Criador Rafael Lannes 11/10/2022

Beleza, vou testar!

Eu tava tentando usar Dependency Injection, mas tava dando erro

Rafael Lannes
Manager Carlos Ferreira 11/10/2022

 Beleza, qualquer problema, retorne o chamado.

Carlos Ferreira
Criador Rafael Lannes 11/10/2022

Opa, carlos beleza?
Então, me deparei com um outro problema. Como te disse, preciso filtrar todas as minhas requisiçoes pelo tenant_id, eu consegui acessar o request() usando o helper.

Como no modelo de Client eu possuo o tenant_id. Gostaria de verificar se quando ele está logado passando o token de autenticação, eu nao precisaria passar o request('uuid').

 

Porém, dentro da função apply no TenantScope o método auth('sanctum')->user() não funciona de jeito nenhum e nem retorna nada, apenas trava o postman com a mensagem Could not get response

Já viu algo parecido?

 

Tentei colocar um array de middlewarePriority mas também não resolveu.

Segue uma print para ilustrar melhor, repara que no meio da requisição o php artisan serve é até reiniciado

https://i.imgur.com/Hhg0uwL.png

 
Rafael Lannes
Criador Rafael Lannes 11/10/2022

O que eu não consegui compreender é como no arquivo TenantScope o helper do request() consegue ser acessado e o auth('sanctum')->user() não

Rafael Lannes
Manager Carlos Ferreira 11/10/2022

Tem o código no GitHub?
Vou precisar analisar com mais profundidade para te ajudar a entender o porque do erro.

--

Já tentou sentar nas configurações o guard default como "sanctum"?
E tentar recuperar o user dessa forma: Auth::user();

Carlos Ferreira
Criador Rafael Lannes 11/10/2022

Opa carlos, tenho o código sim, é nesse arquivo que estou testando 

https://github.com/rafaellannes/enjoy_api/blob/9ad6ecebbd20608222f07f04754d86b2e7b2738b/app/Tenant/Scopes/TenantScope.php

 

Inclusive eu tentei fazer o que você sugeriu, mas quando altero no config o guard para "sanctum" continua travando como se fosse auth('sanctum')->user() 

tentei também usar um middleware na rota para setar a informação no Auth, mas retorna null.

 

Estranho demais, já to perdidaço nisso!

Até tentei usar um try catch pra tentar descobrir algum erro, mas apenas trava e dá esse erro no postman

Rafael Lannes
Criador Rafael Lannes 11/10/2022

PS: como o projeto da API é feita em separado não tenho todas as migrations nesse projeto, mas acredito que dê pra ter uma dimensão melhor sobre o que pode estar acontecendo =/

A minha suspeita é que essa função Aplly() rode antes do middleware do sanctum, possivelmente deve existir uma maneira de ajustar essa prioridade, mas venho pesquisado desde então e não consigo ter muitas saídas!

Rafael Lannes
Manager Carlos Ferreira 11/10/2022

É possível pegar o usuário autenticado, no global scope.

Aqui nessa rota, consegue recuperar o client?
Route::get('/auth/me', function () {
    return \Auth::user();
});

Carlos Ferreira
Criador Rafael Lannes 11/10/2022

Aqui nessa rota, consegue recuperar o client?
Route::get('/auth/me', function () {
    return auth('sanctum')->user() 
});

 

Assim eu consigo

Rafael Lannes
Criador Rafael Lannes 11/10/2022

Porém, não no arquivo de Scope, só no controller

Rafael Lannes
Manager Carlos Ferreira 11/10/2022

Me envia um e-mail ([email protected]), que vou precisar acessar sua maquina para conseguir te ajudar;

Carlos Ferreira
Sabe a Solução? Ajude a resolver!

Precisa estar logado para conseguir responder a este ticket!

Clique Aqui Para Entrar!