Do not speak Portuguese? Translate this site with Google or Bing Translator
20 dicas e truques do Laravel Eloquent

Posted on: December 03, 2021 09:54 AM

Posted by: Renato

Views: 2514

20 dicas e truques do Laravel Eloquent
 

O Eloquent ORM parece um mecanismo simples, mas por baixo do capô, há muitas funções semi-ocultas e maneiras menos conhecidas de conseguir mais com ele. Neste artigo, vou mostrar alguns truques.

1. Incrementos e decrementos

Em vez disso:


 
1$article = Article::find($article_id);
2$article->read_count++;
3$article->save();

Você consegue fazer isso:


 
1$article = Article::find($article_id);
2$article->increment('read_count');

Também funcionarão:


 
1Article::find($article_id)->increment('read_count');
2Article::find($article_id)->increment('read_count', 10); // +10
3Product::find($produce_id)->decrement('stock'); // -1

2. Métodos XorY

O Eloquent tem algumas funções que combinam dois métodos, como “por favor, faça X, caso contrário, faça Y”.

Exemplo 1 - findOrFail():

Ao invés de:


 
1$user = User::find($id);
2if (!$user) { abort (404); }

Fazem isto:


 
1$user = User::findOrFail($id);

Exemplo 2 - firstOrCreate():

Ao invés de:


 
1$user = User::where('email', $email)->first();
2if (!$user) {
3 User::create([
4 'email' => $email
5 ]);
6}

Faça apenas isto:


 
1$user = User::firstOrCreate(['email' => $email]);

3. Método model boot ()

Existe um lugar mágico chamado boot()em um modelo do Eloquent onde você pode substituir o comportamento padrão:


 
1class User extends Model
2{
3 public static function boot()
4 {
5 parent::boot();
6 static::updating(function($model)
7 {
8 // do some logging
9 // override some property like $model->something = transform($something);
10 });
11 }
12}

Provavelmente, um dos exemplos mais populares é definir algum valor de campo no momento da criação do objeto de modelo. Digamos que você queira gerar o campo UUID naquele momento.


 
1public static function boot()
2{
3 parent::boot();
4 self::creating(function ($model) {
5 $model->uuid = (string)Uuid::generate();
6 });
7}

4. Relacionamento com condições e pedidos

Esta é uma maneira típica de definir relacionamento:


 
1public function users() {
2 return $this->hasMany('App\User');
3}

Mas você sabia que neste momento já podemos adicionar whereou orderBy?
Por exemplo, se você deseja um relacionamento específico para algum tipo de usuário, também solicitado por e-mail, você pode fazer o seguinte:


 
1public function approvedUsers() {
2 return $this->hasMany('App\User')->where('approved', 1)->orderBy('email');
3}

5. Propriedades do modelo: carimbos de data / hora, anexos etc.

Existem alguns “parâmetros” de um modelo do Eloquent, na forma de propriedades dessa classe. Os mais populares são provavelmente estes:


 
1class User extends Model {
2 protected $table = 'users';
3 protected $fillable = ['email', 'password']; // which fields can be filled with User::create()
4 protected $dates = ['created_at', 'deleted_at']; // which fields will be Carbon-ized
5 protected $appends = ['field1', 'field2']; // additional values returned in JSON
6}

Mas espere, tem mais:


 
1protected $primaryKey = 'uuid'; // it doesn't have to be "id"
2public $incrementing = false; // and it doesn't even have to be auto-incrementing!
3protected $perPage = 25; // Yes, you can override pagination count PER MODEL (default 15)
4const CREATED_AT = 'created_at';
5const UPDATED_AT = 'updated_at'; // Yes, even those names can be overridden
6public $timestamps = false; // or even not used at all

E tem ainda mais, eu listei os mais interessantes, para mais por favor verifique o código da classe de modelo abstrato padrão e verifique todas as características usadas.


6. Encontre várias entradas

Todo mundo conhece o find()método, certo?


 
1$user = User::find(1);

Estou bastante surpreso como poucas pessoas sabem que ele pode aceitar vários IDs como uma matriz:


 
1$users = User::find([1,2,3]);

7. WhereX

Há uma maneira elegante de transformar isso:


 
1$users = User::where('approved', 1)->get();

Nisso:


 
1$users = User::whereApproved(1)->get();

Sim, você pode alterar o nome de qualquer campo e anexá-lo como um sufixo a “onde” e ele funcionará como um passe de mágica.

Além disso, existem alguns métodos predefinidos no Eloquent, relacionados a data / hora:


 
1User::whereDate('created_at', date('Y-m-d'));
2User::whereDay('created_at', date('d'));
3User::whereMonth('created_at', date('m'));
4User::whereYear('created_at', date('Y'));

8. Ordem por relacionamento

Um “truque” um pouco mais complicado. E se você tiver tópicos de fórum, mas quiser ordená-los pela última postagem ? Requisito bastante comum em fóruns com os últimos tópicos atualizados no topo, certo?

Primeiro, descreva um relacionamento separado para a última postagem sobre o tópico:


 
1public function latestPost()
2{
3 return $this->hasOne(\App\Post::class)->latest();
4}

E então, em nosso controlador, podemos fazer esta “mágica”:


 
1$users = Topic::with('latestPost')->get()->sortByDesc('latestPost.created_at');

9. Eloquent :: when () - não há mais if-else's

Muitos de nós escrevemos consultas condicionais com "if-else", algo assim:


 
1if (request('filter_by') == 'likes') {
2 $query->where('likes', '>', request('likes_amount', 0));
3}
4if (request('filter_by') == 'date') {
5 $query->orderBy('created_at', request('ordering_rule', 'desc'));
6}

Mas há uma maneira melhor - de usar when():


 
1$query = Author::query();
2$query->when(request('filter_by') == 'likes', function ($q) {
3 return $q->where('likes', '>', request('likes_amount', 0));
4});
5$query->when(request('filter_by') == 'date', function ($q) {
6 return $q->orderBy('created_at', request('ordering_rule', 'desc'));
7});

Pode não parecer mais curto ou mais elegante, mas o mais poderoso é passar dos parâmetros:


 
1$query = User::query();
2$query->when(request('role', false), function ($q, $role) {
3 return $q->where('role_id', $role);
4});
5$authors = $query->get();

10. Pertence a modelos padrão

Digamos que você tenha uma postagem pertencente ao autor e, em seguida, ao código Blade:


 
1{{ $post->author->name }}

Mas e se o autor for excluído ou não for definido por algum motivo? Você obterá um erro, algo como “propriedade do não objeto”.

Claro, você pode evitá-lo assim:


 
1{{ $post->author->name ?? '' }}

Mas você pode fazer isso no nível de relacionamento do Eloquent:


 
1public function author()
2{
3 return $this->belongsTo('App\Author')->withDefault();
4}

Neste exemplo, a author()relação retornará um App\Authormodelo vazio se nenhum autor estiver anexado à postagem.

Além disso, podemos atribuir valores de propriedade padrão a esse modelo padrão.


 
1public function author()
2{
3 return $this->belongsTo('App\Author')->withDefault([
4 'name' => 'Guest Author'
5 ]);
6}

11. Pedido por Mutator

Imagine que você tem isso:


 
1function getFullNameAttribute()
2{
3 return $this->attributes['first_name'] . ' ' . $this->attributes['last_name'];
4}

Agora, você quer ordenar por isso full_nameIsso não vai funcionar:


 
1$clients = Client::orderBy('full_name')->get(); // doesn't work

A solução é bastante simples. Precisamos ordenar os resultados depois de obtê-los.


 
1$clients = Client::get()->sortBy('full_name'); // works!

Observe que o nome da função é diferente - não é orderBy , é sortBy .


12. Ordenação padrão no escopo global

E se você quiser que User::all()sempre seja ordenado por namecampo? Você pode atribuir um escopo global. Vamos voltar ao boot()método, que já mencionamos acima.


 
1protected static function boot()
2{
3 parent::boot();
4
5 // Order by name ASC
6 static::addGlobalScope('order', function (Builder $builder) {
7 $builder->orderBy('name', 'asc');
8 });
9}

Leia mais sobre Query Scopes aqui .


13. Métodos de consulta bruta

Às vezes, precisamos adicionar consultas brutas às nossas instruções do Eloquent. Felizmente, existem funções para isso.


 
1// whereRaw
2$orders = DB::table('orders')
3 ->whereRaw('price > IF(state = "TX", ?, 100)', [200])
4 ->get();
5
6// havingRaw
7Product::groupBy('category_id')->havingRaw('COUNT(*) > 1')->get();
8
9// orderByRaw
10User::where('created_at', '>', '2016-01-01')
11 ->orderByRaw('(updated_at - created_at) desc')
12 ->get();

14. Replicar: faça uma cópia de uma linha

Um curto. Sem explicações profundas, esta é a melhor maneira de fazer uma cópia da entrada do banco de dados:


 
1$task = Tasks::find(1);
2$newTask = $task->replicate();
3$newTask->save();

15. Método Chunk () para tabelas grandes

Não exatamente relacionado ao Eloquent, é mais sobre Coleção, mas ainda poderoso - para processar conjuntos de dados maiores, você pode dividi-los em pedaços.

Ao invés de:


 
1$users = User::all();
2foreach ($users as $user) {
3 // ...

Você pode fazer:


 
1User::chunk(100, function ($users) {
2 foreach ($users as $user) {
3 // ...
4 }
5});

16. Crie coisas adicionais ao criar um modelo

Todos nós conhecemos este comando do Artisan:


 
1php artisan make:model Company

Mas você sabia que existem três sinalizadores úteis para gerar arquivos relacionados ao modelo?


 
1php artisan make:model Company -mcr
  • -m irá criar um arquivo de migração
  • -c criará um controlador
  • -r irá indicar que o controlador deve ser engenhoso

17. Substituir updated_at ao salvar

Você sabia que esse ->save()método pode aceitar parâmetros? Como resultado, podemos dizer a ele para “ignorar” a updated_atfuncionalidade padrão a ser preenchida com o carimbo de data / hora atual. Veja isso:


 
1$product = Product::find($id);
2$product->updated_at = '2019-01-01 10:00:00';
3$product->save(['timestamps' => false]);

Aqui estamos substituindo o padrão updated_atpelo pré-definido.


18. Qual é o resultado de uma atualização ()?

Você já se perguntou o que esse código realmente retorna?


 
1$result = $products->whereNull('category_id')->update(['category_id' => 2]);

Quer dizer, a atualização é realizada no banco de dados, mas o que isso $resultconteria?

A resposta é linhas afetadas . Portanto, se você precisar verificar quantas linhas foram afetadas, não precisa chamar mais nada - o update()método retornará esse número para você.


19. Transforme os colchetes em uma consulta do Eloquent

E se você tiver e / ou misturar sua consulta SQL, assim:


 
1... WHERE (gender = 'Male' and age >= 18) or (gender = 'Female' and age >= 65)

Como traduzir para o Eloquent? Este é o caminho errado :


 
1$q->where('gender', 'Male');
2$q->orWhere('age', '>=', 18);
3$q->where('gender', 'Female');
4$q->orWhere('age', '>=', 65);

O pedido estará incorreto. O caminho certo é um pouco mais complicado, usando funções de encerramento como subconsultas:


 
1$q->where(function ($query) {
2 $query->where('gender', 'Male')
3 ->where('age', '>=', 18);
4})->orWhere(function($query) {
5 $query->where('gender', 'Female')
6 ->where('age', '>=', 65);
7})

20. ou Onde com vários parâmetros

Finalmente, você pode passar uma série de parâmetros para orWhere().
Forma “usual”:


 
1$q->where('a', 1);
2$q->orWhere('b', 2);
3$q->orWhere('c', 3);

Você pode fazer assim:


 
1$q->where('a', 1);
2$q->orWhere(['b' => 2, 'c' => 3]);

Fonte: https://laravel-news.com/eloquent-tips-tricks
 

2

Share

Donate to Site


About Author

Renato

Developer

Add a Comment
Comments 0 Comments

No comments yet! Be the first to comment

Blog Search


Categories

OUTROS (15) Variados (109) PHP (130) Laravel (157) Black Hat (3) front-end (28) linux (113) postgresql (39) Docker (26) rest (5) soap (1) webservice (6) October (1) CMS (2) node (7) backend (13) ubuntu (54) devops (25) nodejs (5) npm (2) nvm (1) git (8) firefox (1) react (6) reactnative (5) collections (1) javascript (6) reactjs (7) yarn (0) adb (1) Solid (2) blade (3) models (1) controllers (0) log (1) html (2) hardware (3) aws (14) Transcribe (2) transcription (1) google (4) ibm (1) nuance (1) PHP Swoole (5) mysql (31) macox (4) flutter (1) symfony (1) cor (1) colors (2) homeOffice (2) jobs (3) imagick (2) ec2 (1) sw (1) websocket (1) markdown (1) ckeditor (1) tecnologia (14) faceapp (1) eloquent (14) query (4) sql (40) ddd (3) nginx (9) apache (4) certbot (1) lets-encrypt (3) debian (11) liquid (1) magento (2) ruby (1) LETSENCRYPT (1) Fibonacci (1) wine (1) transaction (1) pendrive (1) boot (1) usb (1) prf (1) policia (2) federal (1) lucena (1) mongodb (4) paypal (1) payment (1) zend (1) vim (4) ciencia (6) js (1) nosql (1) java (1) JasperReports (1) phpjasper (1) covid19 (1) saude (1) athena (1) cinnamon (1) phpunit (2) binaural (1) mysqli (3) database (42) windows (6) vala (1) json (2) oracle (1) mariadb (4) dev (12) webdev (24) s3 (4) storage (1) kitematic (1) gnome (2) web (2) intel (3) piada (1) cron (2) dba (18) lumen (1) ffmpeg (2) android (2) aplicativo (1) fedora (2) shell (4) bash (3) script (3) lider (1) htm (1) csv (1) dropbox (1) db (3) combustivel (2) haru (1) presenter (1) gasolina (1) MeioAmbiente (1) Grunt (1) biologia (1) programming (22) performance (3) brain (1) smartphones (1) telefonia (1) privacidade (1) opensource (3) microg (1) iode (1) ssh (3) zsh (2) terminal (3) dracula (1) spaceship (1) mac (2) idiomas (1) laptop (2) developer (37) api (4) data (1) matematica (1) seguranca (2) 100DaysOfCode (9) hotfix (1) documentation (1) laravelphp (10) RabbitMQ (1) Elasticsearch (1) redis (2) Raspberry (4) Padrao de design (4) JQuery (1) angularjs (4) Dicas (39) Kubernetes (2) vscode (2) backup (1) angular (3) servers (2) pipelines (1) AppSec (1) DevSecOps (4) rust (1) RustLang (1) Mozilla (1) algoritimo (1) sqlite (1) Passport (1) jwt (4) security (2) translate (1) kube (1) iot (1) politica (2) bolsonaro (1) flow (1) podcast (1) Brasil (1) containers (2) traefik (1) networking (1) host (1) POO (2) microservices (2) bug (1) cqrs (1) arquitetura (2) Architecture (3) sail (3) militar (1) artigo (1) economia (1) forcas armadas (1) ffaa (1) autenticacao (1) autorizacao (2) authentication (4) authorization (2) NoCookies (1) wsl (4) memcached (1) macos (2) unix (2) kali-linux (1) linux-tools (5) apple (1) noticias (2) composer (1) rancher (1) k8s (1) escopos (1) orm (1) jenkins (4) github (5) gitlab (3) queue (1) Passwordless (1) sonarqube (1) phpswoole (1) laraveloctane (1) Swoole (1) Swoole (1) octane (1) Structurizr (1) Diagramas (1) c4 (1) c4-models (1) compactar (1) compression (1) messaging (1) restfull (1) eventdrive (1) services (1) http (1) Monolith (1) microservice (1) historia (1) educacao (1) cavalotroia (1) OOD (0) odd (1) chatgpt (1) openai (3) vicuna (1) llama (1) gpt (1) transformers (1) pytorch (1) tensorflow (1) akitando (1) ia (1) nvidia (1) agi (1) guard (1) multiple_authen (2) rpi (1) auth (1) auth (1) livros (2) ElonMusk (2) Oh My Zsh (1) Manjaro (1) BigLinux (2) ArchLinux (1) Migration (1) Error (1) Monitor (1) Filament (1) LaravelFilament (1) replication (1) phpfpm (1) cache (1) vpn (1) l2tp (1) zorin-os (1) optimization (1) scheduling (1) monitoring (2) linkedin (1) community (1) inteligencia-artificial (2) wsl2 (1) maps (1) API_KEY_GOOGLE_MAPS (1) repmgr (1) altadisponibilidade (1) banco (1) modelagemdedados (1) inteligenciadedados (4) governancadedados (1) bancodedados (2) Observability (1) picpay (1) ecommerce (1)

New Articles



Get Latest Updates by Email