Crear un Resource con make:filament-resource
Cada producto necesita su propia «ficha» con su nombre, precio, cuántos tienes… eso es exactamente lo que hace un Resource en Filament.
Es como tener un archivero mágico donde cada producto tiene su tarjeta y puedes agregar, ver, editar o borrar productos cuando quieras.
Crear el modelo y la tablaAntes de poder guardar productos, necesitamos «enseñarle» a Laravel cómo son esos productos. Es como crear una plantilla en blanco.
Abre tu terminal (esa pantalla negra donde escribes comandos) y escribe esto:
📍 Archivo: terminal
php artisan make:model Producto --migration
💡 Esto crea dos cosas: el modelo (la plantilla del producto) y la migración (el plano de la tabla en la base de datos).
Decirle a la base de datos qué campos tendrá cada productoAhora vamos a definir la estructura de nuestra tabla. Es como diseñar un formulario en papel: ¿qué información queremos guardar de cada producto?
Abre el archivo de migración que se acaba de crear (tiene un nombre largo con números y termina en create_productos_table.php) y dentro de la función up() agrega estas líneas:
📝 ESTE ES EL CÓDIGO QUE VAMOS A APRENDER:
📍 Archivo: database/migrations/XXXX_XX_XX_XXXXXX_create_productos_table.php
$table->string('nombre');
$table->text('descripcion')->nullable();
$table->decimal('precio', 10, 2);
$table->integer('stock')->default(0);
$table->boolean('activo')->default(true);
🔍 Vamos a entender línea por línea (como si fuera la primera vez):
$table->string('nombre');
→ Esto crea un campo de texto corto para el nombre. Es como una línea en un formulario donde escribes «Laptop Dell» o «Mouse inalámbrico».
$table->text('descripcion')->nullable();
→ Esto crea un campo grande para descripciones largas. Lo de nullable significa que si no quieres poner descripción, puedes dejarlo en blanco. No es obligatorio.
$table->decimal('precio', 10, 2);
→ Esto guarda números con decimales (como 899.99). El 10 significa que puede tener hasta 10 dígitos en total, y el 2 significa que 2 de esos dígitos son para los centavos después del punto.
$table->integer('stock')->default(0);
→ Esto guarda números enteros (sin decimales) para la cantidad que tienes en bodega. El default(0) significa que si no especificas cuántos tienes, empieza con cero.
$table->boolean('activo')->default(true);
→ Esto es un campo de sí o no (activo/inactivo). El default(true) significa que por defecto los productos están activos cuando los creas.
Crear la tabla de verdad (no solo el plano)Hasta ahora solo hemos dicho «queremos una tabla así». Ahora le decimos a Laravel que la cree de verdad en la base de datos:
📍 Archivo: terminal
php artisan migrate
💡 Si todo salió bien, verás un mensaje verde diciendo que se creó la tabla. ¡Eso significa que ya tienes tu «cajón» listo para guardar productos!
Crear el Resource (el panel de administración)Ahora viene lo bonito. Vamos a crear el panel donde podrás ver, agregar, editar y borrar productos. Es como crear la «ventanilla» donde atenderás tus productos:
📍 Archivo: terminal
php artisan make:filament-resource Producto
Cuando ejecutes esto, Filament te hará 3 preguntas. Responde así:
- «What is the title attribute?» → Escribe:
nombre(le dices que el nombre es lo más importante) - «Would you like a read-only view page?» → Escribe:
no(por ahora no necesitamos una página solo para ver) - «Generate from database columns?» → Escribe:
no(lo haremos paso a paso para aprender)
Un pequeño ajuste importanteAquí está el truco: Filament, por costumbre, usa la palabra
'name' en inglés. Pero nosotros pusimos 'nombre' en español. Es como si Filament estuviera buscando un archivo llamado «name» pero nosotros lo llamamos «nombre». Tenemos que decirle el nombre correcto.
📊 Así se ve tu tabla en la base de datos:
| id | nombre | precio | stock |
|---|---|---|---|
| 1 | Laptop Dell | 899.99 | 10 |
| 2 | Mouse Inalámbrico | 25.50 | 50 |
👆 Ves que el campo se llama nombre (no name)? Ese es el detalle que debemos corregir.
📝 ESTE ES EL CAMBIO QUE DEBES HACER:
📍 Archivo: app/Filament/Resources/Productos/ProductoResource.php
protected static ?string $recordTitleAttribute = 'name';protected static ?string $recordTitleAttribute = 'nombre';
¿Por qué? Porque así se llama el campo en tu base de datos. Es como decirle a Filament: «Oye, cuando muestres un producto, usa el campo que se llama nombre, no busques uno que se llame name«.
🔍 Desglose de esta línea (para que no sea magia negra):
protected
→ Significa «esto es privado, solo se usa dentro de esta clase». Como cuando tienes un secreto que solo tú sabes.
static
→ Significa «esto es de la clase en general, no de cada producto individual». Es como una regla que aplica para todos.
?string
→ Significa «esto es texto». El signo ? significa que podría estar vacío si quisiéramos (pero no lo dejaremos vacío).
$recordTitleAttribute
→ Es el nombre que Filament ya conoce. Es como una palabra clave que Filament busca para saber «¿cuál es el título principal?»
= 'nombre'
→ Le asignamos el valor 'nombre'. Esto le dice a Filament: «Ve a la base de datos y usa el campo que se llama nombre«.
¡Momento de la verdad!Abre tu navegador y entra a
http://tu-proyecto.test/admin (cambia «tu-proyecto» por el nombre de tu proyecto).
Si todo salió bien, deberías ver «Productos» en el menú de la izquierda. ¡Eso significa que lo lograste!
💡 Si haces clic en «Productos», verás una página vacía lista para que empieces a agregar tus primeros productos. Eso lo veremos en la siguiente lección.
📁 ¿Quieres ver el código completo del archivo? (opcional)
Esto es solo para que veas dónde va tu código. No necesitas memorizar todo esto:
📍 Archivo: app/Filament/Resources/Productos/ProductoResource.php
<?php
namespace AppFilamentResourcesProductos;
use AppFilamentResourcesProductosPagesCreateProducto;
use AppFilamentResourcesProductosPagesEditProducto;
use AppFilamentResourcesProductosPagesListProductos;
use AppFilamentResourcesProductosSchemasProductoForm;
use AppFilamentResourcesProductosTablesProductosTable;
use AppModelsProducto;
use BackedEnum;
use FilamentResourcesResource;
use FilamentSchemasSchema;
use FilamentSupportIconsHeroicon;
use FilamentTablesTable;
class ProductoResource extends Resource
{
protected static ?string $model = Producto::class;
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
// 👇 ESTA ES LA LÍNEA QUE CAMBIAMOS NOSOTROS
protected static ?string $recordTitleAttribute = 'nombre';
public static function form(Schema $schema): Schema
{
return ProductoForm::configure($schema);
}
public static function table(Table $table): Table
{
return ProductosTable::configure($table);
}
public static function getRelations(): array
{
return [];
}
public static function getPages(): array
{
return [
'index' => ListProductos::route('/'),
'create' => CreateProducto::route('/create'),
'edit' => EditProducto::route('/{record}/edit'),
];
}
}
🎉 ¿Qué aprendimos hoy?
- Un Resource es como una ficha digital para manejar productos (agregar, ver, editar, borrar)
- Primero creamos el modelo (la plantilla), luego la tabla (donde se guardan los datos), y finalmente el resource (el panel de administración)
- Lo único que tuvimos que cambiar fue decirle a Filament que use
'nombre'en vez de'name'porque así llamamos al campo en español - Todo lo demás lo hizo Filament automáticamente. ¡No es tan complicado como parece!
En la siguiente lección aprenderemos a personalizar el nombre que aparece en el menú. ¡Nos vemos allí! 🚀