Visão geral
Neste tutorial, você aprenderá a usar o MongoDB em um aplicação Laravel criando um sistema simples de alerta de tarefas. O aplicação permite criar, ler, atualizar e excluir tarefas. Além disso, ele envia alertas por e-mail para as próximas tarefas com base em um horário agendado.
Pré-requisitos
Antes de iniciar este tutorial, verifique se você tem os seguintes componentes instalados em seu ambiente de desenvolvimento:
Você também deve configurar um cluster MongoDB Atlas . Para saber como configurar um cluster, consulte o guia de Introdução.
Passos
Instale o pacote MongoDB Laravel .
Para utilizar MongoDB em seu aplicação , você deve instalar o pacote Laravel MongoDB e configurá-lo no arquivo config/database.php.
Instale o pacote usando o seguinte comando:
composer require mongodb/laravel-mongodb
Dica
Se você encontrar um erro ao executar o comando anterior, certifique-se de que a extensão MongoDB PHP esteja instalada. Para saber como instalar, consulte a etapa Instalar a extensão MongoDB PHP no guia de Introdução.
Configure a conexão do banco de dados .
Após a conclusão da instalação do pacote Laravel MongoDB , adicione sua conexão do banco de dados MongoDB ao arquivo config/database.php para concluir a configuração. Adicione a seguinte configuração MongoDB à array connections que contém configurações para outros tipos de banco de dados :
return [ 'connections' => [ 'mongodb' => [ 'driver' => 'mongodb', 'dsn' => env('MONGODB_URI'), 'database' => 'task_reminder', ], // Other connections here ], ];
Seu aplicação obtém o valor dsn do arquivo .env. Navegue até seu arquivo .env. Em seguida, crie um valor para MONGODB_URI e defina-o para o valor da sua string de conexão do MongoDB .
Dica
Para obter sua string de conexão do MongoDB , navegue até seu cluster no MongoDB Atlas. Clique no Connect botão e clique no Drivers Connect your applicationem. Selecione "PHP" no Driver menu de seleção. Copie a string de conexão da caixa de diálogo. Para obter etapas detalhadas sobre como obter sua string de conexão, consulte create-a-connection-string.
Em seu arquivo .env, defina o valor DB_CONNECTION como mongodb para torná-la a conexão padrão do seu aplicação. Edite o valor SESSION_DRIVER e defina-o para mongodb conforme mostrado no seguinte código:
MONGODB_URI=mongodb+srv://YOUR_MONGODB_CONNECTION_STRING DB_CONNECTION=mongodb // Other DB_ values here ... SESSION_DRIVER=mongodb
Configure a autenticação com o Laravel MongoDB.
Depois de instalar e configurar seu aplicação para funcionar com o MongoDB, configure a autenticação. O Laravel simplifica a implementação de autenticação fornecendo pacotes como Laravel MongoDB, Laravel Fortify e Laravel Jetstream. Este tutorial usa o Laravelbreize para autenticação.
Instale o Laravel MongoDB usando o Composer:
composer require laravel/breeze --dev
Após a conclusão da instalação, execute os seguintes comandos:
php artisan key:generate php artisan breeze:install php artisan migrate php artisan db:seed npm install npm run dev
Isso solicitará que você escolha sua pilha preferida e pacote de teste . Para este tutorial, selecione a primeira opção, Lâmina com Alpino:
┌ Which Breeze stack would you like to install? ───────────────┐ │ > ● Blade with Alpine │ │ ○ Livewire (Volt Class API) with Alpine │ │ ○ Livewire (Volt Functional API) with Alpine │ │ ○ React with Inertia │ │ ○ Vue with Inertia │ │ ○ API only │ └──────────────────────────────────────────────────────────────┘
Este comando adiciona visualizações de autenticação, rotas, drivers e outros recursos relacionados ao seu aplicação.
Configure o modelo de usuário e autenticação para MongoDB.
O Laravel Acesa cria um modelo de usuário padrão para bancos de dados SQL. Você deve atualizá-lo para funcionar com o MongoDB e resolver problemas de compatibilidade de limitação de taxa.
Abra o app/Models/User.php e substitua seu conteúdo pelo seguinte:
namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Notifications\Notifiable; use MongoDB\Laravel\Auth\User as MongoUser; class User extends MongoUser { use HasFactory, Notifiable; protected $connection = 'mongodb'; protected $collection = 'users'; /** * The attributes that are mass assignable. * * @var array<int, string> */ protected $fillable = [ 'name', 'email', 'password', ]; /** * The attributes that should be hidden for serialization. * * @var array<int, string> */ protected $hidden = [ 'password', 'remember_token', ]; /** * Get the attributes to cast. * * @return array<string, string> */ protected function casts(): array { return [ 'email_verified_at' => 'datetime', 'password' => 'hashed', ]; } }
Visualize o projeto e teste a conexão do MongoDB .
Envie o projeto usando o servidor integrado do Laravel e confirme se tudo funciona corretamente. No diretório do projeto Laravel, execute o seguinte comando:
php artisan serve
O projeto atende às 127.0.0.1:8000. Se a porta 8000 já estiver em uso, o Laravel mudará para uma nova porta disponível, que imprime no terminal.
Para testar o sistema de autenticação, selecione o botão Register em seu aplicação e crie uma nova conta de usuário. Isso armazena o usuário em seu banco de dados MongoDB e permite que você faça login com essas credenciais. Para este tutorial, você pode definir o nome de usuário como test@example.com e a senha como password.
Para verificar se o pacote Laravel MongoDB foi configurado corretamente, crie uma rota para ping em seu Cluster MongoDB . Adicione o seguinte a routes/web.php:
Route::get('/ping', function (Request $request) { $connection = DB::connection('mongodb'); try { $connection->command(['ping' => 1]); $msg = 'MongoDB is accessible!'; } catch (\MongoDB\Driver\Exception\ConnectionException $e) { $msg = 'You are not connected to MongoDB. Error: ' . $e->getMessage(); } return ['msg' => $msg]; });
Visite esta rota no seu navegador. Com a configuração correta, você verá a mensagem "O MongoDB está acessível! " no seu navegador.
Crie o modelo de tarefa e controlador.
Crie o modelo e o controlador para o recurso de agendamento de tarefas usando o seguinte comando:
php artisan make:model Task --resource --controller
Este comando cria o modelo Task no diretório app/Models e o TaskController no diretório app/Http/Controllers com métodos de recursos.
Crie uma rota para o TaskController navegando até routes/web.php e adicionando o seguinte código:
use App\Http\Controllers\TaskController; // Other route definitions... Route::resource('tasks', TaskController::class)->middleware('auth');
Configure o modelo de tarefa.
Navegue até app/Models/Task.php e substitua o conteúdo do arquivo pelo seguinte código:
namespace App\Models; use MongoDB\Laravel\Eloquent\Model; class Task extends Model { protected $connection = 'mongodb'; protected $table = 'tasks'; protected $fillable = [ 'title', 'description', 'due_date', 'email', 'reminder_time', 'last_notification_date' ]; }
Este código cria o modelo de tarefa com as seguintes especificações:
A declaração
use MongoDB\Laravel\Eloquent\Modelapós o namespace é específica para os modelos do MongoDB . Ele substitui os recursos Eloquent implementados com SQL usando consultas MongoDB .A propriedade
protected $table = 'tasks'é opcional. Especifica o nome da collection MongoDB usada para armazenar os documentos deste modelo.A propriedade
protected $fillableespecifica as propriedades atribuíveis em massa.
Dica
Uma das funcionalidades exclusivas do MongoDB é que ele não exige migrações como os bancos de dados relacionais. Você pode adicionar novos campos diretamente aos seus documentos sem atualizar o modelo ou criar migrações. Esta funcionalidade é útil para lidar com dados dinâmicos.
Crie a lógica TaskController.
Navegue até app/Http/Controllers/TaskController.php e atualize o conteúdo com o seguinte código:
namespace App\Http\Controllers; use App\Models\Task; use Carbon\Carbon; use Illuminate\Http\Request; class TaskController extends Controller { /** * Displays a listing of the resource. */ public function index() { $tasks = Task::where('email', auth()->user()->email)->get(); return view('tasks.index', compact('tasks')); } /** * Shows the form for creating a new resource. */ public function create() { return view('tasks.create'); } /** * Stores a newly created resource in storage. */ public function store(Request $request) { $data = $request->validate([ 'title' => 'required|string|max:255', 'description' => 'nullable|string', 'due_date' => 'required|date', 'reminder_time' => 'required|date', ]); $data['due_date'] = Carbon::parse($request->due_date); $data['reminder_time'] = Carbon::parse($request->reminder_time); $data['email'] = auth()->user()->email; $data['last_notification_date'] = null; Task::create($data); return redirect()->route('tasks.index')->with('success', 'Task created successfully.'); } /** * Displays the specified resource. */ public function show(string $id) { // } /** * Shows the form for editing the specified resource. */ public function edit(string $id) { $tasks = Task::where('id', $id)->get(); return view('tasks.edit', ['tasks' => $tasks]); } /** * Updates the specified resource in storage. */ public function update(Request $request, string $id) { $data = $request->validate([ 'title' => 'required|string|max:255', 'description' => 'nullable|string', 'due_date' => 'required|date', 'reminder_time' => 'required|date', ]); $task = Task::findOrFail($id); $data['due_date'] = Carbon::parse($request->due_date)->format('Y-m-d H:i:s'); $data['reminder_time'] = Carbon::parse($request->reminder_time)->format('Y-m-d H:i:s'); $task->update($data); return redirect()->route('tasks.index')->with('success', 'Task updated successfully.'); } /** * Removes the specified resource from storage. */ public function destroy(string $id) { $task = Task::findOrFail($id); $task->delete(); return redirect()->route('tasks.index')->with('success', 'Task deleted successfully.'); } }
A classe TaskController contém código que lida com as operações CRUD do modelo de tarefa:
O método
index()recupera todas as tarefas pertencentes ao usuário conectado e as envia para o arquivoindex.blade.phppara exibição.O método
create()retorna a visualização do formulário para criar uma nova tarefa.O método
store()valida a entrada, atribui o e-mail do usuário conectado à tarefa e a salva no banco de dados.O método
edit()recupera a tarefa específica a ser editada e a exibe em um formulário de edição.O método
update()salva a tarefa editada na coleção de tarefas do MongoDB .O método
destroy()exclui uma tarefa específica.
Cada operação redireciona de volta para a lista de tarefas com uma mensagem de sucesso para feedback do usuário.
Crie arquivos de visualização para o agendador de tarefas.
No diretório resources/views, crie uma pasta denominada tasks e crie os seguintes arquivos nela:
create.blade.phpedit.blade.phpindex.blade.php
Navegue até resources/views/tasks/create.blade.php e adicione o seguinte conteúdo:
1 <x-app-layout> 2 <x-slot name="header"> 3 <h2 class="font-semibold text-xl text-gray-800 leading-tight"> 4 {{ __('Tasks') }} 5 </h2> 6 </x-slot> 7 8 <div class="py-12"> 9 <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> 10 <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg"> 11 <div class="container mx-auto p-4"> 12 <h2 class="text-2xl font-bold mb-4">Create New Task</h2> 13 14 <form action="{{ route('tasks.store') }}" method="POST"> 15 @csrf 16 17 <div class="mb-4"> 18 <label for="title" class="block text-gray-700">Title:</label> 19 <input type="text" 20 name="title" 21 id="title" 22 required 23 class="border border-gray-300 p-2 w-full" 24 value="{{ old('title') }}"> 25 @error('title') 26 <p class="text-red-500">{{ $message }}</p> 27 @enderror 28 </div> 29 30 <div class="mb-4"> 31 <label for="description" class="block text-gray-700">Description:</label> 32 <textarea name="description" 33 id="description" 34 class="border border-gray-300 p-2 w-full">{{ old('description') }}</textarea> 35 </div> 36 37 <div class="mb-4"> 38 <label for="due_date" class="block text-gray-700">Due Date:</label> 39 <input type="date" 40 name="due_date" 41 id="due_date" 42 required 43 class="border border-gray-300 p-2 w-full" 44 value="{{ old('due_date') }}"> 45 @error('due_date') 46 <p class="text-red-500">{{ $message }}</p> 47 @enderror 48 </div> 49 50 <div class="mb-4"> 51 <label for="reminder_time" class="block text-gray-700">Reminder Time:</label> 52 <input type="datetime-local" 53 name="reminder_time" 54 id="reminder_time" 55 class="border border-gray-300 p-2 w-full" 56 value="{{ old('reminder_time') }}"> 57 </div> 58 59 <button type="submit" 60 class="bg-green-600 text-white p-2 border rounded"> 61 Create Task 62 </button> 63 </form> 64 </div> 65 </div> 66 </div> 67 </div> 68 </x-app-layout>
O formulário contém entradas de texto para title e description e entradas de data e hora para due date e reminder time.
Navegue até resources/views/tasks/edit.blade.php e adicione o seguinte conteúdo:
1 <x-app-layout> 2 <x-slot name="header"> 3 <h2 class="font-semibold text-xl text-gray-800 leading-tight"> 4 {{ __('Edit Task') }} 5 </h2> 6 </x-slot> 7 8 <div class="py-12"> 9 <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> 10 <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg"> 11 <div class="p-6 text-gray-900"> 12 @foreach($tasks as $task) 13 <form action="{{ route('tasks.update', $task->id) }}" method="POST"> 14 @csrf 15 @method('PUT') 16 17 <div class="mb-4"> 18 <label for="title" class="block text-gray-700">Title:</label> 19 <input type="text" 20 name="title" 21 id="title" 22 required 23 class="border border-gray-300 p-2 w-full" 24 value="{{ old('title', $task->title) }}"> 25 @error('title') 26 <p class="text-red-500">{{ $message }}</p> 27 @enderror 28 </div> 29 30 <div class="mb-4"> 31 <label for="description" class="block text-gray-700">Description:</label> 32 <textarea name="description" 33 id="description" 34 class="border border-gray-300 p-2 w-full">{{ old('description', $task->description) }}</textarea> 35 </div> 36 37 <div class="mb-4"> 38 <label for="due_date" class="block text-gray-700">Due Date:</label> 39 <input type="date" 40 name="due_date" 41 id="due_date" 42 required 43 class="border border-gray-300 p-2 w-full" 44 value="{{ old('due_date', $task->due_date) }}"> 45 @error('due_date') 46 <p class="text-red-500">{{ $message }}</p> 47 @enderror 48 </div> 49 50 <div class="mb-4"> 51 <label for="reminder_time" class="block text-gray-700">Reminder Time:</label> 52 <input type="datetime-local" 53 name="reminder_time" 54 id="reminder_time" 55 class="border border-gray-300 p-2 w-full" 56 value="{{ old('reminder_time', $task->reminder_time) }}"> 57 </div> 58 59 <button type="submit" 60 class="bg-blue-500 text-white p-2 rounded"> 61 Update Task 62 </button> 63 </form> 64 @endforeach 65 </div> 66 </div> 67 </div> 68 </div> 69 </x-app-layout>
O formulário de edição contém os mesmos campos de entrada que o formulário de criação e é carregado com os dados da tarefa que está sendo editada.
Navegue até resources/views/tasks/index.blade.php e adicione o seguinte conteúdo:
1 <x-app-layout> 2 <x-slot name="header"> 3 <h2 class="font-semibold text-xl text-gray-800 leading-tight"> 4 {{ __('Tasks') }} 5 </h2> 6 </x-slot> 7 8 <div class="py-12"> 9 <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> 10 <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg"> 11 <div class="p-6 text-gray-900"> 12 <div class="mb-2"> 13 <a href="{{ route('tasks.create') }}" 14 class="p-2 border mb-4"> 15 Create New Task 16 </a> 17 </div> 18 19 <ul class="mt-4"> 20 @foreach ($tasks as $task) 21 <div class="mt-2"> 22 <hr> 23 </div> 24 25 <li> 26 <h1 class="text-2xl"> 27 <strong>{{ $task->title }}</strong> 28 - Due: {{ $task->due_date }} 29 </h1> 30 31 <p class="text-gray-600"> 32 {{ $task->description }} 33 </p> 34 35 <div class="flex gap-2 mt-4"> 36 <div class="p-2 text-white bg-gray-700"> 37 <a href="{{ route('tasks.edit', $task->id) }}"> 38 Edit 39 </a> 40 </div> 41 42 <div class="p-2 text-white bg-red-700 rounded"> 43 <form action="{{ route('tasks.destroy', $task->id) }}" 44 method="POST" 45 style="display:inline;"> 46 @csrf 47 @method('DELETE') 48 <button type="submit">Delete</button> 49 </form> 50 </div> 51 </div> 52 </li> 53 @endforeach 54 </ul> 55 </div> 56 </div> 57 </div> 58 </div> 59 </x-app-layout>
Essa visualização inclui um link para o formulário de criação e percorre todas as tarefas para exibir aquelas pertencentes ao usuário autenticado.
Adiciona link de navegação para tarefas.
Adicione um link para a funcionalidade de tarefa a partir da navegação do seu aplicação . Vá para resources/views/layouts/navigation.blade.php e adicione o seguinte código após o link de navegação do dashboard:
1 // ...existing code ... 2 <div class="hidden space-x-8 sm:-my-px sm:ms-10 sm:flex"> 3 <x-nav-link :href="route('tasks.index')" :active="request()->routeIs('tasks.index')"> 4 {{ __('Tasks') }} 5 </x-nav-link> 6 </div>
Neste ponto, você pode testar as operações CRUD do seu sistema de gerenciamento de tarefas. Certifique-se de que tudo funcione corretamente antes de passar para a próxima seção.
Crie um comando Atlasan personalizado para enviar avisos.
Para implementar o sistema de aviso para tarefas vencidas, crie um comando Personalizado do Atlas para enviar alertas por e-mail e registrar o comando para agendamento automático.
Para criar um comando Atlas personalizado, execute o seguinte código no seu terminal:
php artisan make:command SendTaskReminders
Após criar o comando, atualize o conteúdo do arquivo app/Console/Commands/SendTaskReminders.php com o seguinte código:
namespace App\Console\Commands; use App\Models\Task; use Carbon\Carbon; use Illuminate\Console\Command; use Illuminate\Support\Facades\Mail; class SendTaskReminders extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'app:send-task-reminders'; /** * The console command description. * * @var string */ protected $description = 'Command description'; /** * Execute the console command. */ public function handle() { $now = Carbon::now(); $upcomingTasks = Task::where('last_notification_date', null)->get(); $upcomingTasks = Task::where('last_notification_date', null) ->where('reminder_time', '>=', $now->clone()->subMinutes(10)) ->get(); foreach ($upcomingTasks as $task) { $emailBody = <<<EOF Hello, This is a reminder for your task: Title: {$task->title} Description: {$task->description} Due Date: {$task->due_date} Please make sure to complete it on time! Regards, Your Task Reminder App EOF; Mail::raw($emailBody, function ($message) use ($task) { $message->to($task->email) ->subject("Task Reminder: {$task->title}"); }); $task->last_notification_date = $now; $task->save(); $this->info("Reminder email sent for task: {$task->title}"); } return self::SUCCESS; } }
A lógica principal do comando Personalizado do Mestre está escrita no método handle(). O código obtém o carimbo de data/hora atual usando Carbon::now().
Em seguida, ele consulta o banco de dados para obter todas as tarefas em que reminder_time é menor ou igual ao tempo atual e onde reminder_time é maior ou igual a 10 minutos antes do tempo atual. No MongoDB, todas as datas são armazenadas em UTC. Mesmo que seu servidor use um zona horário diferente , você não precisará alterar o zona horário .
A query busca todas as tarefas vencidas nos próximos 10 minutos. O código percorre os resultados e envia alertas para os e-mails do usuário de tarefas que serão vencidas nos próximos 10 minutos.
Observação
Para que o agendador de tarefas funcione corretamente, você deve configurar seu aplicação para enviar e-mails. Mailtrap.io é uma ferramenta útil para testar o envio de e-mails. Para saber mais, consulte Enviar e-mail no Laravel.
Agende notificações para avisos de tarefas.
Para concluir a configuração, agende o comando Array criado na etapa anterior para executar a cada minuto. Esta abordagem executa automaticamente php
artisan app:send-task-reminders a cada minuto.
Navegue até routes/console.php e adicione o seguinte código:
// ...existing code ... Schedule::command('app:send-task-reminders')->everyMinute();
Para testar se isso funciona, execute o seguinte comando:
php artisan schedule:run
Em um servidor de produção, você deve configurar um tarefa cron para executar o comando php
artisan schedule:run em intervalos regulares.
Em um servidor baseado em Linux ou Unix, você pode abrir seu arquivo de configuração do cron usando o seguinte comando:
crontab -e
Adicione o seguinte código à aba de configuração do cron:
* * * * * /usr/bin/php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
Substitua /usr/bin/php pelo caminho para o binário do PHP e /path-to-your-project pelo caminho completo para o projeto Laravel no servidor. Salve e saia do arquivo.
Para verificar se a tarefa cron está configurada corretamente, execute o seguinte comando:
crontab -l
Resumo
Agora você tem um aplicação agendador de tarefas que usa Laravel e MongoDB. Este tutorial demonstra como realizar as seguintes ações:
Configurar um projeto Laravel para trabalhar com MongoDB
Implemente recursos CRUD para o agendador de tarefas
Crie um comando personalizado do Laravel Atlasan para o sistema de alerta
Agende uma tarefa para executar o comando Mestre em intervalos
Configurar a tarefa cron em um servidor baseado em Linux
Próximos passos
Para saber mais sobre os conceitos abordados neste tutorial, consulte os seguintes recursos:
Exemplos de uso para exemplos de código de operações comuns
Modelos Eloquent para trabalhar com modelos Eloquent