18. Crear Chatbots
Tutorial 18: Crear Chatbots
En este tutorial, implementaremos la funcionalidad para crear nuevos chatbots desde cero. Aprenderemos a añadir el botón de creación, configurar la vista, manejar el formulario y procesar la creación en el controlador.
1. Agregar el Botón de Creación en el Listado
Primero, debemos añadir un botón en la vista de listado (index) que nos permita navegar a la página de creación.
Modificar la Vista Index
resources/views/chatbots/index.blade.php (o su equivalente en Inertia/Vue)
<div>
{{-- Contenedor con flex para alinear título y botón --}}
<div class="flex items-center justify-between mb-4">
<h1 class="text-2xl font-bold">Listado de Chatbots</h1>
{{-- Botón para crear nuevo chatbot --}}
<a href="{{ route('chatbots.create') }}"
class="inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition">
<span class="mr-2">
<svg xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 4v16m8-8H4" />
</svg>
</span>
Crear Chatbot
</a>
</div>
{{-- Resto del contenido del listado --}}
</div>Si usas Livewire o Blade puro:
<div class="flex items-center justify-between mb-6">
<h1 class="text-2xl font-semibold">Mis Chatbots</h1>
<a href="{{ route('chatbots.create') }}"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded flex items-center">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path>
</svg>
Crear Chatbot
</a>
</div>2. Configurar el Controlador - Método create
En el ChatbotController, debemos agregar la lógica para mostrar el formulario de creación.
app/Http/Controllers/ChatbotController.php
use Inertia\Inertia; use App\Models\Chatbot; public function create() { // Pasamos un chatbot vacío a la vista return Inertia::render('Chatbots/Create', [ 'chatbot' => new Chatbot() ]); }
Si usas Livewire o Blade tradicional:
public function create() { return view('chatbots.create', [ 'chatbot' => new Chatbot() ]); }
Crear la Vista de Creación
Para ahorrar tiempo y mantener consistencia, podemos duplicar la vista de edición y adaptarla para creación.
resources/views/chatbots/create.blade.php (Blade)
o
resources/js/Pages/Chatbots/Create.vue (Inertia/Vue)
3. Adaptar el Formulario para Creación
La vista de creación será muy similar a la de edición, pero con algunas diferencias clave:
Estructura del Formulario
{{-- resources/views/chatbots/create.blade.php --}}
@extends('layouts.app')
@section('content')
<div class="container mx-auto px-4 py-8">
<div class="max-w-2xl mx-auto">
<h1 class="text-2xl font-bold mb-6">Crear Nuevo Chatbot</h1>
{{-- Formulario --}}
<form action="{{ route('chatbots.store') }}" method="POST">
@csrf
{{-- Campo: Nombre --}}
<div class="mb-4">
<label for="name" class="block text-sm font-medium text-gray-700 mb-2">
Nombre del Chatbot
</label>
<input type="text"
id="name"
name="name"
value="{{ old('name') }}"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Ej: Asistente de Ventas">
@error('name')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
{{-- Campo: Descripción --}}
<div class="mb-4">
<label for="description" class="block text-sm font-medium text-gray-700 mb-2">
Descripción
</label>
<textarea id="description"
name="description"
rows="4"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Describe el propósito de este chatbot...">{{ old('description') }}</textarea>
@error('description')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
{{-- Botón de envío --}}
<div class="flex items-center justify-end">
<a href="{{ route('chatbots.index') }}"
class="px-4 py-2 text-sm text-gray-600 hover:text-gray-800 mr-2">
Cancelar
</a>
<button type="submit"
class="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition">
Crear Chatbot
</button>
</div>
</form>
</div>
</div>
@endsectionPara Inertia.js (Vue)
<template> <div class="container mx-auto px-4 py-8"> <div class="max-w-2xl mx-auto"> <h1 class="text-2xl font-bold mb-6">Crear Nuevo Chatbot</h1> <form @submit.prevent="handleSubmit"> <div class="mb-4"> <label for="name" class="block text-sm font-medium text-gray-700 mb-2"> Nombre del Chatbot </label> <input type="text" id="name" v-model="form.name" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Ej: Asistente de Ventas"> <p v-if="form.errors.name" class="mt-1 text-sm text-red-600"> {{ form.errors.name }} </p> </div> <div class="mb-4"> <label for="description" class="block text-sm font-medium text-gray-700 mb-2"> Descripción </label> <textarea id="description" v-model="form.description" rows="4" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Describe el propósito de este chatbot..."></textarea> <p v-if="form.errors.description" class="mt-1 text-sm text-red-600"> {{ form.errors.description }} </p> </div> <div class="flex items-center justify-end"> <Link :href="route('chatbots.index')" class="px-4 py-2 text-sm text-gray-600 hover:text-gray-800 mr-2"> Cancelar </Link> <button type="submit" class="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition"> Crear Chatbot </button> </div> </form> </div> </div> </template> <script setup> import { useForm } from '@inertiajs/vue3'; import { Link } from '@inertiajs/vue3'; const form = useForm({ name: '', description: '', }); const handleSubmit = () => { form.post(route('chatbots.store')); }; </script>
4. Procesar la Creación - Método store
En el controlador, implementamos la lógica para guardar el nuevo chatbot.
app/Http/Controllers/ChatbotController.php
use Illuminate\Http\Request; use App\Models\Chatbot; use App\Http\Requests\ChatbotRequest; // Usando FormRequest para validación public function store(ChatbotRequest $request) { // Crear el chatbot asociado al usuario autenticado $chatbot = $request->user()->chatbots()->create($request->validated()); // Redireccionar a la página de detalles o al listado // Opción 1: Redirigir al listado return redirect()->route('chatbots.index') ->with('success', '¡Chatbot creado exitosamente!'); // Opción 2: Redirigir a la página de detalles del nuevo chatbot // return redirect()->route('chatbots.show', $chatbot) // ->with('success', '¡Chatbot creado exitosamente!'); }
Validación con FormRequest
Creamos un FormRequest para manejar la validación de manera limpia:
app/Http/Requests/ChatbotRequest.php
namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class ChatbotRequest extends FormRequest { public function authorize() { return true; // O verificar permisos aquí } public function rules() { return [ 'name' => 'required|string|max:255|unique:chatbots,name', 'description' => 'nullable|string|max:1000', ]; } public function messages() { return [ 'name.required' => 'El nombre del chatbot es obligatorio', 'name.unique' => 'Ya existe un chatbot con este nombre', 'name.max' => 'El nombre no puede tener más de 255 caracteres', 'description.max' => 'La descripción no puede tener más de 1000 caracteres', ]; } }
5. Resumen del Flujo de Creación
Usuario hace clic en "Crear Chatbot" desde el listado.
Navegación a la ruta
chatbots.create.Controlador
create()retorna la vista con un modelo vacío.Usuario completa el formulario y hace clic en "Crear".
Envío POST a la ruta
chatbots.store.Validación a través del
ChatbotRequest.Creación del nuevo chatbot asociado al usuario autenticado.
Redirección al listado o a la página de detalles.
Feedback con mensaje de éxito.
6. Estructura de Rutas Completa
routes/web.php
use App\Http\Controllers\ChatbotController; Route::resource('chatbots', ChatbotController::class) ->middleware(['auth']);
Esto generará automáticamente todas las rutas RESTful:
GET /chatbots→ indexGET /chatbots/create→ createPOST /chatbots→ storeGET /chatbots/{chatbot}→ showGET /chatbots/{chatbot}/edit→ editPUT/PATCH /chatbots/{chatbot}→ updateDELETE /chatbots/{chatbot}→ destroy
7. Código Completo del Controlador
app/Http/Controllers/ChatbotController.php
<?php namespace App\Http\Controllers; use App\Models\Chatbot; use App\Http\Requests\ChatbotRequest; use Illuminate\Http\Request; use Inertia\Inertia; class ChatbotController extends Controller { public function index() { $chatbots = auth()->user()->chatbots()->paginate(10); if (request()->wantsJson()) { return response()->json($chatbots); } return Inertia::render('Chatbots/Index', [ 'chatbots' => $chatbots ]); } public function create() { return Inertia::render('Chatbots/Create', [ 'chatbot' => new Chatbot() ]); } public function store(ChatbotRequest $request) { $chatbot = $request->user()->chatbots()->create($request->validated()); return redirect()->route('chatbots.index') ->with('success', '¡Chatbot creado exitosamente!'); } public function show(Chatbot $chatbot) { $this->authorize('view', $chatbot); return Inertia::render('Chatbots/Show', [ 'chatbot' => $chatbot ]); } public function edit(Chatbot $chatbot) { $this->authorize('update', $chatbot); return Inertia::render('Chatbots/Edit', [ 'chatbot' => $chatbot ]); } public function update(ChatbotRequest $request, Chatbot $chatbot) { $this->authorize('update', $chatbot); $chatbot->update($request->validated()); return redirect()->back() ->with('success', '¡Chatbot actualizado exitosamente!'); } public function destroy(Chatbot $chatbot) { $this->authorize('delete', $chatbot); $chatbot->delete(); return redirect()->route('chatbots.index') ->with('success', '¡Chatbot eliminado exitosamente!'); } }
8. Mejoras Adicionales
Agregar Políticas de Autorización
app/Policies/ChatbotPolicy.php
namespace App\Policies; use App\Models\User; use App\Models\Chatbot; class ChatbotPolicy { public function view(User $user, Chatbot $chatbot) { return $user->id === $chatbot->user_id; } public function create(User $user) { return true; // Todos los usuarios autenticados pueden crear } public function update(User $user, Chatbot $chatbot) { return $user->id === $chatbot->user_id; } public function delete(User $user, Chatbot $chatbot) { return $user->id === $chatbot->user_id; } }
Estilos CSS para el Botón
.btn-create { @apply inline-flex items-center px-4 py-2 bg-blue-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-blue-700 active:bg-blue-800 focus:outline-none focus:border-blue-800 focus:ring focus:ring-blue-200 disabled:opacity-25 transition; }
Notificaciones con Toast
// En tu layout principal Livewire.on('chatbot-created', () => { toast.success('¡Chatbot creado exitosamente!'); });
9. Verificación Final
Al completar este tutorial, deberías tener:
✅ Botón "Crear Chatbot" visible en el listado
✅ Página de creación con formulario funcional
✅ Validación de datos en el servidor
✅ Asociación automática del chatbot al usuario autenticado
✅ Redirección después de la creación
✅ Mensaje de éxito para el usuario
✅ Código limpio y organizado
Conclusión
¡Has implementado exitosamente la funcionalidad de creación de chatbots! Ahora los usuarios pueden:
Ver el listado de sus chatbots
Hacer clic en "Crear Chatbot"
Completar el formulario con nombre y descripción
Guardar el nuevo chatbot que automáticamente se asocia a su cuenta
Este flujo sigue las mejores prácticas de Laravel, usando:
FormRequest para validación
Relaciones Eloquent para asociación de usuarios
Inertia.js para SPA moderno (o Blade para tradicional)
Políticas para autorización
¡Ya puedes crear chatbots fácilmente desde tu aplicación
Comentarios
Publicar un comentario