Laravel Tinker - La Consola Interactiva de Laravel

 

 Laravel Tinker - La Consola Interactiva de Laravel

Introducción

Laravel Tinker es una poderosa consola interactiva (REPL) que te permite interactuar con tu aplicación Laravel directamente desde la línea de comandos. Es una herramienta indispensable para desarrolladores que permite probar código, consultar la base de datos, depurar y experimentar con Eloquent en tiempo real.

Índice

  1. ¿Qué es Laravel Tinker?

  2. Instalación y Configuración

  3. Comandos Básicos de Tinker

  4. Trabajando con Modelos y Eloquent

  5. Operaciones CRUD en Tinker

  6. Consultas Avanzadas

  7. Trabajando con Relaciones

  8. Funciones Útiles de Tinker

  9. Depuración y Testing

  10. Ejercicios Prácticos

  11. Consejos y Trucos


1. ¿Qué es Laravel Tinker?

Laravel Tinker es un REPL (Read-Eval-Print Loop) que utiliza el componente PsySH. Te permite ejecutar código PHP en el contexto de tu aplicación Laravel.

Características principales

  • Interacción en tiempo real con tu aplicación

  • Acceso a todos los modelos y clases de Laravel

  • Ejecución de consultas Eloquent directamente

  • Pruebas rápidas de código sin necesidad de crear rutas

  • Depuración de problemas específicos

  • Exploración de datos y relaciones

Iniciar Tinker

bash
# Iniciar Tinker
php artisan tinker

# Salir de Tinker
>>> exit
# o presiona Ctrl + D

2. Instalación y Configuración

Verificar instalación

bash
# Verificar que Tinker está instalado
php artisan tinker --version

# Si no está instalado, instalarlo
composer require laravel/tinker --dev

Configuración de alias

Puedes crear un alias para Tinker en tu archivo .bashrc o .zshrc:

bash
# Agregar alias
alias tinker='php artisan tinker'

# Recargar configuración
source ~/.bashrc  # o source ~/.zshrc

Configuración del archivo config/tinker.php

php
<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Comandos de Auto-Completado
    |--------------------------------------------------------------------------
    */
    'commands' => [
        // Comandos personalizados
    ],

    /*
    |--------------------------------------------------------------------------
    | Alias para Clases
    |--------------------------------------------------------------------------
    */
    'aliases' => [
        'App\Models\Pastel' => 'Pastel',
        'App\Models\Categoria' => 'Categoria',
        'App\Models\Product' => 'Product',
    ],

    /*
    |--------------------------------------------------------------------------
    | Funciones Globales
    |--------------------------------------------------------------------------
    */
    'functions' => [
        'dd' => 'dump_and_die',
        'dump' => 'var_dump',
    ],
];

3. Comandos Básicos de Tinker

Comandos de navegación

bash
# Iniciar Tinker
php artisan tinker

# Ver ayuda
>>> help

# Ver comandos disponibles
>>> ls

# Listar variables
>>> vars

# Limpiar pantalla
>>> cls

# Salir
>>> exit
>>> quit
>>> Ctrl + D

# Ver historial
>>> history

# Ejecutar archivo
>>> exec('ruta/archivo.php')

# Mostrar documentación de una función
>>> doc('dd')

# Mostrar información de una clase
>>> info('App\Models\Pastel')

Comandos de PsySH

php
// Ver el valor de una variable
>>> $pastel = new Pastel();
>>> $pastel

// Mostrar tipo de dato
>>> typeof($pastel)

// Ver métodos disponibles
>>> $pastel->methods()

// Ver propiedades
>>> $pastel->props()

// Ver constantes
>>> $pastel->consts()

// Ver documentación
>>> doc('Pastel::where')

4. Trabajando con Modelos y Eloquent

Importar modelos

php
// Forma larga
>>> $pastel = new App\Models\Pastel();

// Con alias (configurado previamente)
>>> $pastel = new Pastel();

// Usando el facade
>>> use App\Models\Pastel;
>>> $pastel = new Pastel();

// Ver todos los modelos disponibles
>>> get_declared_classes()

Consultas básicas

php
// Obtener todos los registros
>>> Pastel::all();

// Obtener el primer registro
>>> Pastel::first();

// Obtener por ID
>>> Pastel::find(1);
>>> Pastel::findOrFail(1);

// Contar registros
>>> Pastel::count();

// Verificar existencia
>>> Pastel::where('sabor', 'chocolate')->exists();
>>> Pastel::where('sabor', 'chocolate')->doesntExist();

// Obtener solo algunos campos
>>> Pastel::select('nombre', 'precio')->get();

// Obtener valores de una columna
>>> Pastel::pluck('nombre');
>>> Pastel::pluck('nombre', 'id');

// Obtener valor específico
>>> Pastel::where('id', 1)->value('nombre');

// Paginación
>>> Pastel::paginate(10);
>>> Pastel::paginate(10)->toArray();

Consultas con condiciones

php
// WHERE simple
>>> Pastel::where('sabor', 'chocolate')->get();
>>> Pastel::where('precio', '>', 100)->get();

// WHERE con múltiples condiciones
>>> Pastel::where('sabor', 'chocolate')
    ->where('precio', '>', 100)
    ->get();

// OR WHERE
>>> Pastel::where('sabor', 'chocolate')
    ->orWhere('sabor', 'vainilla')
    ->get();

// WHERE IN
>>> Pastel::whereIn('sabor', ['chocolate', 'vainilla'])->get();

// WHERE BETWEEN
>>> Pastel::whereBetween('precio', [50, 200])->get();

// WHERE LIKE
>>> Pastel::where('nombre', 'LIKE', '%chocolate%')->get();

// WHERE NULL
>>> Pastel::whereNull('descripcion')->get();
>>> Pastel::whereNotNull('descripcion')->get();

// WHERE DATE
>>> Pastel::whereDate('created_at', '2024-01-01')->get();
>>> Pastel::whereMonth('created_at', 1)->get();
>>> Pastel::whereYear('created_at', 2024)->get();

Ordenamiento y límites

php
// Ordenar ascendente
>>> Pastel::orderBy('nombre')->get();
>>> Pastel::orderBy('precio')->get();

// Ordenar descendente
>>> Pastel::orderBy('precio', 'desc')->get();

// Múltiples ordenamientos
>>> Pastel::orderBy('sabor')->orderBy('precio', 'desc')->get();

// Límite y offset
>>> Pastel::limit(5)->get();
>>> Pastel::offset(10)->limit(5)->get();

// Aleatorio
>>> Pastel::inRandomOrder()->get();
>>> Pastel::inRandomOrder()->first();

// Últimos registros
>>> Pastel::latest()->get();
>>> Pastel::latest()->first();

5. Operaciones CRUD en Tinker

CREATE - Crear registros

php
// Método 1: Usando new y save()
>>> $pastel = new Pastel();
>>> $pastel->nombre = 'Pastel de Prueba';
>>> $pastel->sabor = 'chocolate';
>>> $pastel->precio = 150.00;
>>> $pastel->save();

// Método 2: Usando create()
>>> $pastel = Pastel::create([
    'nombre' => 'Pastel con create',
    'sabor' => 'vainilla',
    'precio' => 120.00,
    'disponible' => true
]);

// Método 3: Usando firstOrCreate()
>>> $pastel = Pastel::firstOrCreate(
    ['nombre' => 'Pastel Único'],
    ['sabor' => 'fresa', 'precio' => 180]
);

// Método 4: Usando firstOrNew()
>>> $pastel = Pastel::firstOrNew(
    ['nombre' => 'Pastel Nuevo'],
    ['sabor' => 'cheesecake', 'precio' => 200]
);
>>> $pastel->save();

// Método 5: updateOrCreate()
>>> $pastel = Pastel::updateOrCreate(
    ['nombre' => 'Pastel Especial'],
    ['sabor' => 'chocolate', 'precio' => 250]
);

// Verificar el registro creado
>>> $pastel->id
>>> $pastel->nombre
>>> $pastel->toArray()

READ - Leer registros

php
// Obtener todos
>>> $pasteles = Pastel::all();
>>> count($pasteles)

// Obtener el primero
>>> $pastel = Pastel::first();
>>> $pastel->nombre

// Obtener por ID
>>> $pastel = Pastel::find(1);

// Obtener con condiciones
>>> $pasteles = Pastel::where('disponible', true)->get();

// Obtener con relaciones
>>> $pastel = Pastel::with('categoria')->find(1);

// Ver datos formateados
>>> $pastel->toArray()
>>> $pastel->toJson()

// Acceder a atributos
>>> $pastel->nombre
>>> $pastel->precio
>>> $pastel->created_at->format('d/m/Y')

UPDATE - Actualizar registros

php
// Método 1: Encontrar y actualizar
>>> $pastel = Pastel::find(1);
>>> $pastel->precio = 200;
>>> $pastel->save();

// Método 2: Usando update()
>>> Pastel::where('id', 1)->update([
    'precio' => 180,
    'disponible' => false
]);

// Método 3: Encontrar y actualizar en una línea
>>> Pastel::find(1)->update(['precio' => 190]);

// Método 4: Incrementar/Decrementar
>>> Pastel::where('id', 1)->increment('precio', 10);
>>> Pastel::where('id', 1)->decrement('precio', 5);

// Actualizar múltiples registros
>>> Pastel::where('sabor', 'chocolate')
    ->update(['disponible' => false]);

// Verificar actualización
>>> $pastel = Pastel::find(1);
>>> $pastel->precio
>>> $pastel->disponible

DELETE - Eliminar registros

php
// Método 1: Encontrar y eliminar
>>> $pastel = Pastel::find(1);
>>> $pastel->delete();

// Método 2: Eliminar por ID
>>> Pastel::destroy(1);
>>> Pastel::destroy([1, 2, 3]);

// Método 3: Eliminar con condición
>>> Pastel::where('precio', '<', 50)->delete();

// Método 4: Soft Delete (si está habilitado)
>>> $pastel = Pastel::find(1);
>>> $pastel->delete();  // Marca deleted_at

// Verificar eliminados
>>> Pastel::withTrashed()->get();
>>> Pastel::onlyTrashed()->get();

// Restaurar
>>> $pastel = Pastel::withTrashed()->find(1);
>>> $pastel->restore();

// Eliminar permanentemente
>>> $pastel->forceDelete();

6. Consultas Avanzadas

Agregaciones

php
// Contar
>>> Pastel::count();
>>> Pastel::where('sabor', 'chocolate')->count();

// Suma
>>> Pastel::sum('precio');
>>> Pastel::where('sabor', 'chocolate')->sum('precio');

// Promedio
>>> Pastel::avg('precio');
>>> Pastel::where('sabor', 'chocolate')->avg('precio');

// Máximo
>>> Pastel::max('precio');
>>> Pastel::where('sabor', 'chocolate')->max('precio');

// Mínimo
>>> Pastel::min('precio');
>>> Pastel::where('sabor', 'chocolate')->min('precio');

Agrupamiento y having

php
// Group by
>>> Pastel::select('sabor', Pastel::raw('count(*) as total'))
    ->groupBy('sabor')
    ->get();

// Group by con having
>>> Pastel::select('sabor', Pastel::raw('avg(precio) as promedio'))
    ->groupBy('sabor')
    ->having('promedio', '>', 100)
    ->get();

// Múltiples agregaciones
>>> Pastel::select(
    'sabor',
    Pastel::raw('count(*) as total'),
    Pastel::raw('avg(precio) as promedio'),
    Pastel::raw('sum(precio) as suma_total')
)
->groupBy('sabor')
->get();

Subconsultas

php
// Subconsulta en WHERE
>>> $pasteles = Pastel::where('precio', '>', function($query) {
    $query->select(Pastel::raw('avg(precio)'))
          ->from('pasteles');
})->get();

// Subconsulta en SELECT
>>> $pasteles = Pastel::select('nombre', 'precio')
    ->selectSub(function($query) {
        $query->select(Pastel::raw('avg(precio)'))
              ->from('pasteles');
    }, 'precio_promedio')
    ->get();

// Subconsulta con whereExists
>>> $pasteles = Pastel::whereExists(function($query) {
    $query->select(Pastel::raw(1))
          ->from('categorias')
          ->whereColumn('pasteles.categoria_id', 'categorias.id');
})->get();

Raw Queries

php
// SELECT RAW
>>> $pasteles = Pastel::select(
    Pastel::raw('nombre, precio, precio * 1.16 as precio_con_iva')
)->get();

// WHERE RAW
>>> $pasteles = Pastel::whereRaw('precio > ?', [100])->get();

// ORDER BY RAW
>>> $pasteles = Pastel::orderByRaw('precio DESC, nombre ASC')->get();

// RAW con valores nombrados
>>> $pasteles = Pastel::whereRaw('precio > :precio', ['precio' => 100])->get();

// Expresiones RAW complejas
>>> $pasteles = Pastel::select(
    Pastel::raw('DATE(created_at) as fecha'),
    Pastel::raw('COUNT(*) as total')
)
->groupBy('fecha')
->get();

Scopes y relaciones

php
// Usando scopes definidos en el modelo
>>> $pasteles = Pastel::disponible()->get();
>>> $pasteles = Pastel::chocolate()->get();
>>> $pasteles = Pastel::precioEntre(50, 200)->get();

// Scopes con parámetros
>>> $pasteles = Pastel::sabor('chocolate')->get();

// Cargar relaciones
>>> $pastel = Pastel::with('categoria')->find(1);
>>> $pastel->categoria->nombre

// Cargar relaciones anidadas
>>> $pastel = Pastel::with('categoria.pasteles')->find(1);

// Cargar solo ciertas columnas de la relación
>>> $pastel = Pastel::with('categoria:id,nombre')->find(1);

// Cargar relaciones con condiciones
>>> $pastel = Pastel::with(['categoria' => function($query) {
    $query->where('activa', true);
}])->find(1);

7. Trabajando con Relaciones

Relaciones Belongs To

php
// Obtener la categoría de un pastel
>>> $pastel = Pastel::find(1);
>>> $categoria = $pastel->categoria;
>>> $categoria->nombre

// Crear pastel con categoría
>>> $categoria = Categoria::create([
    'nombre' => 'Tortas Especiales',
    'descripcion' => 'Tortas para ocasiones especiales'
]);

>>> $pastel = new Pastel([
    'nombre' => 'Pastel de Categoría',
    'sabor' => 'chocolate',
    'precio' => 300
]);
>>> $pastel->categoria()->associate($categoria);
>>> $pastel->save();

// Cambiar categoría
>>> $nuevaCategoria = Categoria::find(2);
>>> $pastel->categoria()->associate($nuevaCategoria);
>>> $pastel->save();

// Eliminar relación
>>> $pastel->categoria()->dissociate();
>>> $pastel->save();

Relaciones Has Many

php
// Obtener todos los pasteles de una categoría
>>> $categoria = Categoria::find(1);
>>> $pasteles = $categoria->pasteles;
>>> $pasteles->count();

// Crear pastel en la categoría
>>> $categoria = Categoria::find(1);
>>> $pastel = $categoria->pasteles()->create([
    'nombre' => 'Pastel de la Categoría',
    'sabor' => 'vainilla',
    'precio' => 150
]);

// Crear múltiples pasteles
>>> $categoria->pasteles()->createMany([
    ['nombre' => 'Pastel 1', 'sabor' => 'chocolate', 'precio' => 100],
    ['nombre' => 'Pastel 2', 'sabor' => 'vainilla', 'precio' => 120]
]);

// Agregar con relación existente
>>> $pastel = Pastel::find(2);
>>> $categoria->pasteles()->save($pastel);

// Contar pasteles de la categoría
>>> $categoria->pasteles()->count();

// Obtener pasteles con condiciones
>>> $categoria->pasteles()->where('precio', '>', 100)->get();

Relaciones Many to Many

php
// Obtener ingredientes de un pastel
>>> $pastel = Pastel::find(1);
>>> $ingredientes = $pastel->ingredientes;
>>> $ingredientes->count();

// Agregar ingrediente (attach)
>>> $ingrediente = Ingrediente::find(1);
>>> $pastel->ingredientes()->attach($ingrediente->id);

// Agregar con datos pivot
>>> $pastel->ingredientes()->attach($ingrediente->id, [
    'cantidad' => 100,
    'unidad' => 'g'
]);

// Agregar múltiples ingredientes
>>> $pastel->ingredientes()->attach([1, 2, 3]);

// Desvincular ingrediente (detach)
>>> $pastel->ingredientes()->detach(1);

// Desvincular todos los ingredientes
>>> $pastel->ingredientes()->detach();

// Sincronizar ingredientes
>>> $pastel->ingredientes()->sync([1, 2, 3]);

// Obtener datos del pivot
>>> $pastel = Pastel::with('ingredientes')->find(1);
>>> foreach($pastel->ingredientes as $ingrediente) {
    echo $ingrediente->pivot->cantidad;
    echo $ingrediente->pivot->unidad;
}

Relaciones Polimórficas

php
// Obtener imágenes de un pastel
>>> $pastel = Pastel::find(1);
>>> $imagenes = $pastel->imagenes;

// Crear imagen
>>> $pastel->imagenes()->create([
    'url' => 'http://ejemplo.com/imagen.jpg',
    'alt' => 'Descripción de la imagen'
]);

// Crear múltiples imágenes
>>> $pastel->imagenes()->createMany([
    ['url' => 'http://ejemplo.com/imagen1.jpg', 'alt' => 'Imagen 1'],
    ['url' => 'http://ejemplo.com/imagen2.jpg', 'alt' => 'Imagen 2']
]);

8. Funciones Útiles de Tinker

Función dd() (Dump and Die)

php
// Mostrar datos y detener
>>> dd($pastel);
>>> dd($pasteles->toArray());
>>> dd($pastel->toJson());

// Mostrar múltiples variables
>>> dd($pastel, $categoria, $ingredientes);

// Mostrar con contexto
>>> dd('Pastel encontrado', $pastel);

Función dump()

php
// Mostrar datos sin detener
>>> dump($pastel);
>>> dump($pastel->toArray());

// Mostrar múltiples
>>> dump($pastel, $categoria);

Función collect()

php
// Crear colección
>>> $coleccion = collect([1, 2, 3, 4, 5]);

// Filtrar colección
>>> $coleccion->filter(function($item) {
    return $item > 2;
});

// Mapear colección
>>> $coleccion->map(function($item) {
    return $item * 2;
});

// Colección de modelos
>>> $coleccion = Pastel::all()->collect();
>>> $coleccion->pluck('nombre');
>>> $coleccion->where('disponible', true);

Función app()

php
// Obtener instancia de la aplicación
>>> app();

// Resolver dependencias
>>> $service = app(PastelService::class);

// Obtener ayudantes
>>> app('db')->table('pasteles')->get();
>>> app('cache')->get('key');

// Obtener configuración
>>> app('config')->get('app.timezone');

Función resolve()

php
// Resolver una clase del contenedor
>>> $service = resolve(PastelService::class);

// Resolver con parámetros
>>> $service = resolve(PastelService::class, ['param' => 'value']);

9. Depuración y Testing

Verificar conexión a base de datos

php
// Verificar conexión
>>> DB::connection()->getPdo();
>>> DB::connection()->getDatabaseName();

// Verificar tablas
>>> DB::select('SHOW TABLES');
>>> DB::select('DESCRIBE pasteles');

// Verificar última consulta
>>> DB::enableQueryLog();
>>> $pasteles = Pastel::all();
>>> DB::getQueryLog();

Pruebas con relaciones

php
// Crear datos de prueba
>>> $categoria = Categoria::create([
    'nombre' => 'Categoría Test',
    'descripcion' => 'Descripción Test'
]);

>>> $pastel = Pastel::create([
    'nombre' => 'Pastel Test',
    'sabor' => 'chocolate',
    'precio' => 100,
    'categoria_id' => $categoria->id
]);

// Verificar relaciones
>>> $categoria->pasteles()->count();
>>> $pastel->categoria->nombre;

// Probar scopes
>>> Pastel::disponible()->get();
>>> Pastel::sabor('chocolate')->get();

// Probar validaciones
>>> try {
    Pastel::create(['nombre' => null]);
} catch (\Exception $e) {
    dump($e->getMessage());
}

Pruebas de rendimiento

php
// Medir tiempo de ejecución
>>> $inicio = microtime(true);
>>> $pasteles = Pastel::with('categoria')->get();
>>> $fin = microtime(true);
>>> echo $fin - $inicio;

// Optimizar consultas
>>> DB::enableQueryLog();
>>> $pasteles = Pastel::with('categoria')->get();
>>> DB::getQueryLog();

// Probar con datos masivos
>>> $start = now();
>>> Pastel::factory(1000)->create();
>>> echo now()->diffInSeconds($start);

10. Ejercicios Prácticos

Ejercicio 1: CRUD Básico

php
// 1. Crear un nuevo pastel
>>> $pastel = Pastel::create([
    'nombre' => 'Pastel de Ejercicio',
    'sabor' => 'fresa',
    'precio' => 130.50,
    'disponible' => true,
    'descripcion' => 'Pastel creado en Tinker'
]);

// 2. Verificar que se creó
>>> $pastel->id
>>> $pastel->nombre

// 3. Actualizar el pastel
>>> $pastel->update(['precio' => 150]);

// 4. Verificar actualización
>>> $pastel->precio

// 5. Eliminar el pastel
>>> $pastel->delete();

// 6. Verificar que se eliminó
>>> Pastel::find($pastel->id)

Ejercicio 2: Consultas Avanzadas

php
// 1. Pasteles con precio mayor al promedio
>>> $promedio = Pastel::avg('precio');
>>> $caros = Pastel::where('precio', '>', $promedio)->get();
>>> $caros->count();

// 2. Agrupar por sabor y contar
>>> Pastel::select('sabor', Pastel::raw('count(*) as total'))
    ->groupBy('sabor')
    ->get();

// 3. Pasteles creados hoy
>>> Pastel::whereDate('created_at', now()->toDateString())->get();

// 4. Pasteles con stock bajo (< 10)
>>> Pastel::where('stock', '<', 10)->get();

// 5. Top 5 pasteles más caros
>>> Pastel::orderBy('precio', 'desc')->limit(5)->get();

Ejercicio 3: Trabajando con Relaciones

php
// 1. Crear una categoría
>>> $categoria = Categoria::create([
    'nombre' => 'Tortas Especiales',
    'descripcion' => 'Tortas para ocasiones especiales'
]);

// 2. Crear pasteles para la categoría
>>> $pastel1 = $categoria->pasteles()->create([
    'nombre' => 'Torta de Bodas',
    'sabor' => 'cheesecake',
    'precio' => 350
]);

// 3. Obtener todos los pasteles de la categoría
>>> $categoria->pasteles->count();

// 4. Crear relación many-to-many con ingredientes
>>> $ingrediente = Ingrediente::create([
    'nombre' => 'Fresa',
    'stock' => 50,
    'unidad' => 'kg'
]);

// 5. Agregar ingrediente al pastel
>>> $pastel1->ingredientes()->attach($ingrediente->id, [
    'cantidad' => 0.5,
    'unidad' => 'kg'
]);

// 6. Verificar relación
>>> $pastel1->ingredientes;

Ejercicio 4: Eager Loading

php
// 1. Sin eager loading (N+1 problema)
>>> $pasteles = Pastel::all();
>>> foreach($pasteles as $p) {
    dump($p->categoria->nombre);
}

// 2. Con eager loading (una consulta)
>>> $pasteles = Pastel::with('categoria')->get();
>>> foreach($pasteles as $p) {
    dump($p->categoria->nombre);
}

// 3. Eager loading con condiciones
>>> $pasteles = Pastel::with(['categoria' => function($q) {
    $q->where('activa', true);
}])->get();

// 4. Cargar relaciones anidadas
>>> $pasteles = Pastel::with('categoria.pasteles')->get();

Ejercicio 5: Scopes y Filtros

php
// 1. Definir scope en el modelo (desde Tinker no se puede, pero podemos probarlo)

// 2. Usar scopes existentes
>>> Pastel::disponible()->get();
>>> Pastel::chocolate()->get();

// 3. Combinar scopes
>>> Pastel::disponible()->chocolate()->get();

// 4. Scope con parámetros
>>> Pastel::sabor('vainilla')->get();

// 5. Crear consulta personalizada
>>> Pastel::where('sabor', 'chocolate')
    ->where('precio', '>', 100)
    ->orderBy('nombre')
    ->get();

11. Consejos y Trucos

Atajos de teclado

bash
# Autocompletar
Tab

# Historial de comandos
↑ ↓

# Buscar en historial
Ctrl + R

# Limpiar pantalla
Ctrl + L

# Ir al inicio de línea
Ctrl + A

# Ir al final de línea
Ctrl + E

# Eliminar línea
Ctrl + U

# Salir de Tinker
Ctrl + D  # o escribir exit

Trucos útiles

php
// 1. Usar variables globales
>>> $_pasteles = Pastel::all();  // Para reutilizar

// 2. Guardar consultas comunes
>>> $caros = fn() => Pastel::where('precio', '>', 100)->get();
>>> $caros();

// 3. Crear funciones personalizadas
>>> function getPastelesDisponibles() {
    return Pastel::where('disponible', true)->get();
}
>>> getPastelesDisponibles();

// 4. Usar colecciones para transformar datos
>>> Pastel::all()->map(function($p) {
    return $p->nombre . ' - $' . $p->precio;
});

// 5. Exportar datos a JSON
>>> file_put_contents('pasteles.json', Pastel::all()->toJson());

// 6. Importar datos desde JSON
>>> $data = json_decode(file_get_contents('pasteles.json'), true);
>>> collect($data)->each(function($item) {
    Pastel::create($item);
});

// 7. Ejecutar comandos del sistema
>>> shell_exec('php artisan migrate');

// 8. Ver estructura de la tabla
>>> DB::select('DESCRIBE pasteles');

// 9. Ver estadísticas de la base de datos
>>> DB::select('SHOW TABLE STATUS LIKE "pasteles"');

// 10. Ver consultas SQL generadas
>>> DB::enableQueryLog();
>>> Pastel::where('precio', '>', 100)->get();
>>> DB::getQueryLog();

Personalizar Tinker

php
// En config/tinker.php

// 1. Agregar alias
'aliases' => [
    'Pastel' => 'App\Models\Pastel',
    'Categoria' => 'App\Models\Categoria',
    'DB' => 'Illuminate\Support\Facades\DB',
],

// 2. Agregar comandos personalizados
'commands' => [
    // ...
],

// 3. Configurar funciones globales
'functions' => [
    'dd' => 'dump_and_die',
    'dump' => 'var_dump',
],

Comandos útiles con Tinker

bash
# 1. Ejecutar un script desde Tinker
php artisan tinker --execute="Pastel::all()"

# 2. Ejecutar archivo
php artisan tinker --execute="require 'mi_script.php'"

# 3. Ejecutar Tinker con un archivo de configuración
php artisan tinker --config=mi_config.php

# 4. Ver versión de Tinker
php artisan tinker --version

# 5. Ayuda de Tinker
php artisan tinker --help

Ejercicio de Consolidación

Sistema de Reportes con Tinker

php
// 1. Crear función para reporte de ventas
>>> function reporteVentas($fechaInicio, $fechaFin) {
    $ventas = Venta::whereBetween('fecha_venta', [
        $fechaInicio,
        $fechaFin
    ])->get();
    
    return [
        'total' => $ventas->count(),
        'total_ingresos' => $ventas->sum('total'),
        'promedio_venta' => $ventas->avg('total'),
        'producto_mas_vendido' => $ventas->groupBy('pastel_id')
            ->map(function($item) {
                return $item->sum('cantidad');
            })
            ->sortDesc()
            ->keys()
            ->first()
    ];
}

// 2. Ejecutar reporte
>>> reporteVentas('2024-01-01', '2024-01-31');

// 3. Crear función para inventario
>>> function inventarioBajo($limite = 10) {
    return Pastel::where('stock', '<=', $limite)
        ->select('nombre', 'stock')
        ->get();
}

// 4. Ejecutar inventario
>>> inventarioBajo();

// 5. Crear función para productos populares
>>> function productosPopulares($limite = 5) {
    return Venta::select('pastel_id', 
        Venta::raw('SUM(cantidad) as total_vendido'))
        ->groupBy('pastel_id')
        ->orderBy('total_vendido', 'desc')
        ->limit($limite)
        ->with('pastel')
        ->get();
}

// 6. Ejecutar productos populares
>>> productosPopulares();

Resumen

CaracterísticaDescripciónComando/Ejemplo
Iniciar TinkerAbre la consola interactivaphp artisan tinker
Consultas EloquentPrueba consultas en tiempo realPastel::all()
CRUDCrear, leer, actualizar, eliminarcreate(), update(), delete()
RelacionesPrueba relaciones entre modelos$pastel->categoria
ScopesUsa scopes definidosPastel::disponible()
AgregacionesFunciones de agregacióncount(), sum(), avg()
Eager LoadingCarga anticipada de relacioneswith('categoria')
DebugDepuración de códigodd(), dump()
Raw QueriesSQL directamenteDB::select()

¡Laravel Tinker es una herramienta esencial que te ahorrará horas de desarrollo y depuración

Comentarios

Entradas más populares de este blog

Tutorial CRUD con Laravel 12-Pastel::factory(50)->create();

CRUD Completo con Laravel 12 - Guía Práctica Paso a Paso-productos

CRUD en Laravel 12 con Git - Guía para Principiantes