03 - Controladores en Laravel 12
Controladores en Laravel (sin modelos)
En este tutorial aprenderás a crear un controlador, definir un método que retorne una vista con datos y vincularlo a una ruta, todo sin usar modelos. Solo trabajaremos con arreglos de prueba………………………………………………………………
1. ¿Qué es un controlador?
Un controlador es una clase que agrupa la lógica de manejo de peticiones HTTP. En lugar de poner toda la lógica en las rutas (closures), los controladores permiten organizar el código en métodos reutilizables.
2. Crear un controlador con Artisan
Ejecuta en la terminal (en la raíz de tu proyecto Laravel):
bash
php artisan make:controller TareaController
Esto creará el archivo app/Http/Controllers/TareaController.php.
3. Definir un método index
Abre el controlador recién creado y agrega un método index que devuelva una vista con un arreglo de tareas.
php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TareaController extends Controller
{
public function index()
{
// Datos de ejemplo (sin modelos)
$tareas = [
['id' => 1, 'nombre' => 'Comprar pan'],
['id' => 2, 'nombre' => 'Estudiar Laravel'],
['id' => 3, 'nombre' => 'Hacer ejercicio'],
];
// Retorna la vista 'tareas.index' y le pasa la variable $tareas
return view('tareas.index', compact('tareas'));
}
}
compact('tareas') crea un arreglo asociativo ['tareas' => $tareas] que la vista recibirá.
La vista debe existir en resources/views/tareas/index.blade.php.
4. Crear la vista (sin CSS)
Crea el directorio tareas dentro de resources/views y dentro coloca index.blade.php con el siguiente contenido:
blade
<!DOCTYPE html>
<html>
<head>
<title>Lista de tareas</title>
</head>
<body>
<h1>Mis tareas</h1>
<ul>
@foreach ($tareas as $tarea)
<li>{{ $tarea['nombre'] }} (ID: {{ $tarea['id'] }})</li>
@endforeach
</ul>
</body>
</html>
Usamos Blade @foreach para recorrer el arreglo.
Mostramos el nombre y el ID de cada tarea.
5. Registrar la ruta
Abre routes/web.php y añade:
php
use App\Http\Controllers\TareaController;
Route::get('/tareas', [TareaController::class, 'index']);
Esto asigna la URL /tareas al método index del TareaController.
6. Probar la aplicación
Inicia el servidor de desarrollo:
bash
php artisan serve
Abre tu navegador en http://localhost:8000/tareas y verás la lista de tareas renderizada.
7. Explicación del flujo
El usuario hace una petición GET a /tareas.
Laravel enruta la petición al método index de TareaController.
El método prepara los datos (el arreglo $tareas) y llama a view('tareas.index', compact('tareas')).
Blade renderiza la vista con la variable $tareas disponible.
El HTML resultante se envía al navegador.
8. Buenas prácticas básicas
Nombres de métodos: Usa verbos HTTP (index, show, create, store, edit, update, destroy) para acciones típicas.
Pasar datos: Siempre usa compact() o arreglos explícitos (['tareas' => $tareas]).
Organización: Agrupa rutas relacionadas con Route::resource() (opcional, pero útil cuando tengas CRUD).
Resumen
Los controladores centralizan la lógica de tus rutas.
Los métodos retornan vistas con datos.
Las rutas enlazan URLs con métodos del controlador.
No necesitas modelos para empezar; puedes usar arreglos de prueba.
2. Obtener Todo el Contenido del Request
Laravel inyecta automáticamente el objeto
Illuminate\Http\Request en los métodos del controlador.
Ejemplo: Recuperar todos los datos del request
use Illuminate\Http\Request;
class UserController extends Controller
{
public function store(Request $request)
{
// Obtener todos los datos del request (formulario, JSON, etc.)
$allData = $request->all();
// Mostrar los datos (útil para debugging)
dd($allData);
// También puedes usar:
// $request->input() → Equivalente a all(), pero permite valores por defecto
}
}
📌 Uso común:
$request->all() → Devuelve un array asociativo con todos los inputs.
$request->input() → Similar a all(), pero permite definir un valor por defecto si el campo no existe.
3. Validar Inputs Específicos
Laravel ofrece validación integrada para asegurar que los datos cumplan ciertas reglas.
Ejemplo: Validar campos obligatorios
public function store(Request $request)
{
// Validación básica
$validatedData = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|min:8',
]);
// Si pasa la validación, continuamos
return response()->json(['success' => 'Usuario creado!']);
}
📌 Reglas comunes:
required → El campo es obligatorio.
email → Debe ser un email válido.
unique:users → El email no debe existir en la tabla users.
min:8 → Mínimo 8 caracteres.
💡 Métodos alternativos para acceder a inputs específicos:
php
$name = $request->input('name'); // Obtiene el campo 'name'
$email = $request->email; // Sintaxis alternativa (propiedad dinámica)
$defaultValue = $request->input('role', 'user'); // Valor por defecto si no existef
FLUJO DE DATOS EN EL CRUD
📥 1. Del Modelo al Controlador (Obtener datos)
php
// Obtener todos los registros
$productos = Producto::all();
// Obtener un registro específico
$producto = Producto::find($id);
$producto = Producto::findOrFail($id); // Lanza error 404 si no existe
// Obtener con condiciones
$productosActivos = Producto::where('activo', true)->get();
// Obtener el último registro
$ultimoProducto = Producto::latest()->first();
// Obtener con relaciones (si tienes)
$producto = Producto::with('categoria')->find($id);
📤 2. Del Controlador a la Vista (Inyectar datos)
Método 1: Usando compact()
php
public function index()
{
$productos = Producto::all();
$titulo = "Lista de Productos";
return view('productos.index', compact('productos', 'titulo'));
}
Método 2: Usando with()
php
public function show($id)
{
$producto = Producto::findOrFail($id);
return view('productos.show')->with('producto', $producto);
}
Método 3: Usando array asociativo
php
public function edit($id)
{
$producto = Producto::findOrFail($id);
$categorias = Categoria::all();
return view('productos.edit', [
'producto' => $producto,
'categorias' => $categorias,
'modo' => 'edición'
]);
}
📥 3. De la Vista al Controlador (Recibir datos)
Para formularios GET (búsquedas, filtros):
php
public function index(Request $request)
{
// Obtener parámetros de la URL
$busqueda = $request->input('buscar');
$categoria = $request->query('categoria');
// También puedes usar
$busqueda = $request->get('buscar');
$busqueda = $request->buscar; // Si existe en la URL
// Ejemplo de búsqueda
$productos = Producto::where('nombre', 'LIKE', "%{$busqueda}%")
->when($categoria, function($query) use ($categoria) {
return $query->where('categoria_id', $categoria);
})
->get();
return view('productos.index', compact('productos'));
}
Para formularios POST (crear, actualizar):
php
public function store(Request $request)
{
// Forma 1: Obtener todos los datos
$datos = $request->all();
// Forma 2: Obtener solo algunos campos
$nombre = $request->input('nombre');
$precio = $request->input('precio');
// Forma 3: Obtener con validación (recomendado)
$validated = $request->validate([
'nombre' => 'required|max:255',
'precio' => 'required|numeric|min:0',
'descripcion' => 'nullable|string'
]);
// Guardar usando los datos validados
$producto = Producto::create($validated);
}
📤 4. Del Controlador a la Vista con Redirección
php
public function store(Request $request)
{
// Validar y guardar
$validated = $request->validate([
'nombre' => 'required|max:255',
'precio' => 'required|numeric'
]);
$producto = Producto::create($validated);
// 🔥 DIFERENTES FORMAS DE REDIRECCIONAR
// 1. Redirigir a una ruta con nombre
return redirect()->route('productos.index');
// 2. Redirigir a una URL específica
return redirect('/productos');
// 3. Redirigir al detalle del producto creado
return redirect()->route('productos.show', $producto->id);
// 4. Redirigir hacia atrás
return redirect()->back();
// 5. Redirigir con mensaje flash
return redirect()->route('productos.index')
->with('success', 'Producto creado exitosamente');
}
💬 MENSAJES FLASH (Sistema de notificaciones)
En el Controlador (Guardar mensaje):
php
// Mensaje de éxito
return redirect()->route('productos.index')
->with('success', '¡Producto creado correctamente!');
// Mensaje de error
return redirect()->back()
->with('error', 'Hubo un problema al guardar el producto');
// Mensaje de advertencia
return redirect()->route('productos.index')
->with('warning', 'El producto no tiene stock');
// Múltiples mensajes
return redirect()->route('productos.index')
->with([
'success' => 'Producto actualizado',
'info' => 'Revisa los cambios realizados'
]);
// Mensaje con datos adicionales
return redirect()->route('productos.show', $producto->id)
->with('success', 'Producto actualizado')
->with('producto_id', $producto->id);
En la Vista (Mostrar mensajes):
4. ¿Cómo pasar el arreglo desde la ruta?
Puedes hacerlo de dos maneras comunes:
Opción A – Usando un closure en routes/web.php
php
use Illuminate\Support\Facades\Route;
Route::get('/tareas', function () {
$tareas = [
['id' => 1, 'nombre' => 'Comprar pan'],
['id' => 2, 'nombre' => 'Estudiar Laravel'],
['id' => 3, 'nombre' => 'Hacer ejercicio'],
];
return view('tareas.index', compact('tareas'));
});
Opción B – Usando un controlador
Primero, crea el controlador (ej. TareaController) con un método index:
php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TareaController extends Controller
{
public function index()
{
$tareas = [
['id' => 1, 'nombre' => 'Comprar pan'],
['id' => 2, 'nombre' => 'Estudiar Laravel'],
['id' => 3, 'nombre' => 'Hacer ejercicio'],
];
return view('tareas.index', compact('tareas'));
}
}
Luego, en routes/web.php:
php
use App\Http\Controllers\TareaController;
Route::get('/tareas', [TareaController::class, 'index']);
Comentarios
Publicar un comentario