Do not speak Portuguese? Translate this site with Google or Bing Translator
Usando Laravel 8 e Model Observers

Posted on: October 22, 2021 08:48 PM

Posted by: Renato

Categories: Laravel webdev

Views: 9498

 Usando Laravel 8 e Model Observers

Laravel Model Observers é um ótimo recurso. Os observadores são usados ​​para agrupar ouvintes de eventos para um modelo. Os nomes dos métodos das classes Observers referem-se ao evento do Eloquent que você deseja ouvir. Esses métodos recebem o modelo como seu único argumento. O Laravel não inclui um diretório padrão para observadores. Além disso, o comando artesão para gerar observadores também não está disponível por padrão.

exemplo simples.

Iniciando o projeto

Crie um novo projeto laravel chamado Observables executando o seguinte comando:

composer create-project --prefer-dist laravel/laravel observers

Configure seu banco de dados e adicione as credenciais no arquivo .env. Estaremos demonstrando observadores por meio de um exemplo de produto simples. Primeiro crie um modelo de produto, controlador e migração executando o seguinte comando:

 

php artisan make:model Product -mc

Adicionamos sinalizadores m e c no comando acima. Eles também criarão a migração e o controlador para o modelo, respectivamente.

Agora, atualize o esquema no arquivo de migração que criamos na etapa anterior. Ele será denominado create_products_table.php.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
    Schema::create('products', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->text('description');
        $table->integer('price');
        $table->integer('quantity');
        $table->timestamps();
    });
}

Execute o seguinte comando para migrar seu banco de dados:

 

php artisan migrate

Ele criará uma tabela de produtos. Agora vamos configurar nossas rotas no arquivo routes / web.php. Haverá duas rotas para criar um produto e armazenar um produto. Aqui está o conteúdo:

Route::get('/product', [ProductController::class, 'create']);
Route::post('/product', [ProductController::class, 'store']);

Criação de visão e lógica de back-end

Agora vamos criar nossa visão. Crie uma nova visão chamada create.blade.php no diretório resources / views. Copie o conteúdo abaixo para a visualização.

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Model Observer</title>
 
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
</head>
<body>
<div class="container" style="margin-top: 50px;">
<div class="row">
<div class="col-sm-10 offset-sm-1">
@if($message = session()->pull('message'))
<div class="alert alert-success">{{ $message }}</div>
@endif
<form method="post" action="/product">
{{ csrf_field() }}
<div class="form-group">
<label for="name">Name:</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Enter Product Name">
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea name="description" id="description" class="form-control"
placeholder="Enter Product Description"></textarea>
</div>
<div class="form-group">
<label for="price">Price</label>
<input type="number" class="form-control" id="price" name="price" placeholder="Enter Product Price">
</div>
<div class="form-group">
<label for="quantity">Quantity</label>
<input type="number" class="form-control" id="quantity" name="quantity"
placeholder="Enter Product Quantity">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary" name="submit">Submit</button>
</div>
</form>
@if(count($errors))
<ul class="alert alert-danger well">
@foreach($errors->all() as $error)
<li class="list-unstyled">{{ $error }}</li>
@endforeach
</ul>
@endif
</div>
</div>
 
 
 
@if(count($products))
<hr class="dl-horizontal">
 
<div class="row">
<div class="col-sm-10 offset-sm-1">
<table class="table table-dark">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Description</th>
<th scope="col">Quantity</th>
<th scope="col">Price</th>
</tr>
</thead>
<tbody>
@foreach($products as $product)
<tr>
<th scope="row">{{ $loop->iteration }}</th>
<td>{{ $product->name }}</td>
<td>{{ $product->description }}</td>
<td>{{ $product->quantity }}</td>
<td>{{ $product->price }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endif
</div>
</body>
</html>

...

Nesta visão, estamos simplesmente criando um formulário para criar um produto usando o estilo bootstrap 4. O link para o arquivo css de bootstrap é adicionado na seção head. Depois disso, estamos adicionando uma tabela que irá mostrar todos os produtos disponíveis. Na parte superior, há uma caixa de alerta que mostrará se a criação do produto foi bem-sucedida.

Agora, vamos configurar nosso controlador. Copie o conteúdo abaixo para o arquivo ProductController.php.

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\Request;
use App\Models\Product;
 
class ProductController extends Controller
{
public function create()
{
$products = Product::all();
return view('create', compact('products'));
}
 
public function store(Request $request)
{
$request->validate([
'name' => 'required',
'description' => 'required',
'price' => 'required|numeric',
'quantity' => 'required|numeric'
]);
 
$product = new Product();
$product->name = $request->name;
$product->description = $request->description;
$product->price = $request->price;
$product->quantity = $request->quantity;
$product->save();
 
return redirect('/product')->with('message', 'Product created successfully');
}
}

.

No método de criação, estamos simplesmente obtendo todos os modelos de produtos disponíveis e retornando a visualização.

Em seguida, no método de armazenamento, primeiro os dados são validados e, em seguida, um novo produto é criado e salvo no banco de dados. Em seguida, redirecionamos de volta para a página do produto com a mensagem de sucesso que é mostrada na parte superior da página.

Usando Observadores de Modelo

Agora, digamos que o preço do produto precise ser atualizado. Temos que adicionar alguns impostos ao preço do produto. Além disso, para qualquer produto criado com quantidade superior a 10, daremos a eles 50% de compensação no imposto. Mas não queremos adicionar essa lógica ao nosso controlador. Podemos usar eventos de modelo que são disparados automaticamente pelo laravel quando o novo registro é criado, atualizado ou excluído.

Esta é a lista de todos os eventos, modelo eloquente acionado que podemos conectar

  • retrieved
  • creating
  • created
  • updating
  • updated
  • saving
  • saved
  • deleting
  • deleted
  • restoring
  • restored

Você pode encontrar eventos mais eloquentes nos documentos oficiais de laravel. Agora vamos escrever nossa lógica para o método de inicialização presente em app / Provides / AppServiceProvider.php.

- official laravel docs.

<?php
 
namespace App\Providers;
 
use Illuminate\Support\ServiceProvider;
 
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
 
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
\App\Models\Product::creating(function ($model) {
$tax = .20;
 
if ($model->quantity < 10) { $model->price += $model->price * $tax;
} else if ($model->quantity >= 10) {
$model->price += $model->price * ($tax / 2);
}
});
}
}

.

Agora, no momento da criação, estamos substituindo o valor do preço com base em sua quantidade. Portanto, aqui usamos a criação de eventos de modelo para fazer o trabalho.

Também podemos criar uma classe dedicada que fornece métodos de eventos eloquentes para um modelo específico.
Criação de observadores de modelo dedicados

Adicionar todo o código do observador em AppServiceProvider não é uma boa escolha. Podemos criar classes dedicadas para cada modelo. Primeiro, temos que criar um provedor de serviços. Execute o seguinte comando para criá-lo:

 

php artisan make:provider ProductModelServiceProvider

Registre o provedor de serviços adicionando a seguinte entrada à matriz de fornecedores no arquivo config / app.php:

 

1
App\Providers\ProductModelServiceProvider::class,

.

Os observadores não podem ser criados por meio da linha de comando por padrão. Então, vamos criar um diretório Observer dentro da pasta do app. Dentro da pasta Observer, crie o arquivo ProductObserver.php com o seguinte conteúdo:

<?php
 
namespace App\Observer;
 
use App\Models\Product;
 
class ProductObserver
{
public function creating(Product $product)
{
$tax = .20;
 
if ($product->quantity < 10) {
$product->price += $product->price * $tax;
} else if ($product->quantity >= 10) {
$product->price += $product->price * ($tax / 2);
}
}
}

.

Vá para o arquivo ProductModelServiceProvider.php e adicione o seguinte no método de inicialização. Ele dirá a laravel que estamos observando o modelo Product na classe ProductObserver.

1
\App\Product::observe(\App\Observer\ProductObserver::class);

Agora remova o observador de criação que adicionamos no arquivo AppServiceProvider.php. O carregamento automático dos arquivos pode não funcionar corretamente porque criamos uma pasta e adicionamos nosso arquivo observável. Execute os dois comandos a seguir, um por um, para se certificar de que não haverá erros:

 

# Autoloading of files
composer dump

# Configure the cache
php artisan config:cache

Agora teste o aplicativo e você verá que o preço é alterado de acordo com a quantidade.

É assim que podemos usar Observadores de Modelo no aplicativo Laravel. Eles são muito úteis para refatorar nosso código e trabalhar com o cache.

Esta é a aparência do aplicativo:

Você pode encontrar o código-fonte completo para este aplicativo simples aqui

- https://gitlab.com/cpdrenato/laravel-8-observers

- https://www.youtube.com/watch?v=iU1jiZgQjZ8

 

 
 

 

 


7

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 (16) Variados (109) PHP (133) Laravel (171) Black Hat (3) front-end (29) linux (114) postgresql (39) Docker (28) rest (5) soap (1) webservice (6) October (1) CMS (2) node (7) backend (13) ubuntu (56) devops (25) nodejs (5) npm (3) nvm (1) git (8) firefox (1) react (7) reactnative (5) collections (1) javascript (7) reactjs (8) 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 (2) 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 (12) 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 (5) data (1) matematica (1) seguranca (2) 100DaysOfCode (9) hotfix (1) documentation (1) laravelphp (10) RabbitMQ (3) Elasticsearch (1) redis (2) Raspberry (4) Padrao de design (4) JQuery (1) angularjs (4) Dicas (43) Kubernetes (3) 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 (2) jwt (5) security (2) translate (1) kube (2) iot (1) politica (2) bolsonaro (1) flow (1) podcast (1) Brasil (1) containers (3) traefik (1) networking (1) host (1) POO (2) microservices (2) bug (1) cqrs (1) arquitetura (3) Architecture (4) sail (3) militar (1) artigo (1) economia (1) forcas armadas (1) ffaa (1) autenticacao (2) autorizacao (2) authentication (4) authorization (3) 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) Curisidades (1) Samurai (1) KubeCon (1) GitOps (1) Axios (1) Fetch (1) Deepin (1) vue (4) nuxt (1) PKCE (1) Oauth2 (2) webhook (1) TypeScript (1) tailwind (1) gource (2)

New Articles



Get Latest Updates by Email