Las rutas se guardan en routes/web.php y se debe definir el tipo de peticion
- GET
- POST
- PUT
- PATCH
Route::get('/test/{id}/{category?}', function ($id, $category = null) {
//return "hola Alex este es el post" . request('id');
return ($category) ? "hola Alex este es el post {$id} y la categoria es {$category}" : "hola Alex este es el post {$id}";
});
// Language Translation
Route::get('index/{locale}', [App\Http\Controllers\HomeController::class, 'lang']);
Route::get('/', [App\Http\Controllers\HomeController::class, 'root'])->name('root');Supongamos que estás desarrollando una aplicación de administración de productos. Tienes un controlador llamado ProductController que maneja las operaciones relacionadas con los productos, como listar todos los productos, mostrar un producto específico, crear, editar y eliminar productos.
Aquí tienes una ruta para listar todos los productos y una para mostrar un producto específico por su ID:
// Ruta para listar todos los productos
Route::get('/products', [ProductController::class, 'index'])->name('products.index');
// Ruta para mostrar un producto específico
Route::get('/products/{id}', [ProductController::class, 'show'])->name('products.show');-
Ruta para Listar Productos:
Route::get('/products', [ProductController::class, 'index'])->name('products.index');
- URL: La ruta responde a una solicitud HTTP GET en la URL
/products. - Controlador y Método: Está asociado al método
indexdelProductController, que se encarga de listar todos los productos. - Nombre de la Ruta: Se le asigna el nombre
'products.index', lo que permite referirse a esta ruta en otras partes de la aplicación usando ese nombre en lugar de la URL directa.
Ejemplo de uso:
// Generar la URL para listar productos $url = route('products.index'); // Resultado: "/products" // Redireccionar a la página de productos return redirect()->route('products.index');
- URL: La ruta responde a una solicitud HTTP GET en la URL
-
Ruta para Mostrar un Producto Específico:
Route::get('/products/{id}', [ProductController::class, 'show'])->name('products.show');
- URL: La ruta responde a una solicitud HTTP GET en la URL
/products/{id}, donde{id}es un parámetro dinámico que representa el ID del producto. - Controlador y Método: Está asociado al método
showdelProductController, que se encarga de mostrar los detalles de un producto específico. - Nombre de la Ruta: Se le asigna el nombre
'products.show'.
Ejemplo de uso:
// Generar la URL para mostrar un producto con ID 5 $url = route('products.show', ['id' => 5]); // Resultado: "/products/5" // Redireccionar a la página del producto con ID 5 return redirect()->route('products.show', ['id' => 5]);
- URL: La ruta responde a una solicitud HTTP GET en la URL
- Mantenibilidad: Si cambias la URL de la ruta, no necesitas actualizar todos los lugares donde se usa la ruta. Solo cambias la URL en la definición de la ruta.
- Claridad: Usar nombres de rutas hace que el código sea más claro y fácil de leer, ya que indica la intención del código.
- Conveniencia: Generar URLs y redirecciones es más sencillo y menos propenso a errores cuando se usan nombres de rutas.
- Con
name('products.index'): Puedes referirte a la ruta que lista todos los productos usando'products.index'. - Con
name('products.show'): Puedes referirte a la ruta que muestra un producto específico usando'products.show'.
Esto ayuda a que el código sea más limpio y fácil de mantener.
En vez de hacer los procesos en las rutas, esto lo hacemos con los controladores
php artisan make:controller ItemsControllerSí, el método __invoke sigue utilizándose en Laravel 11. En Laravel, el método __invoke es una característica de PHP que permite a los objetos ser llamados como si fueran funciones. Esto es útil para crear controladores de una sola acción, middleware, y otros componentes que necesitan comportarse como funciones pero aún así mantener la flexibilidad de las clases.
Por ejemplo, en Laravel puedes definir un controlador de una sola acción así:
namespace App\Http\Controllers;
class MyController
{
public function __invoke()
{
return 'Hello, world!';
}
}Y luego lo registras en las rutas como una ruta de controlador de una sola acción:
use App\Http\Controllers\MyController;
Route::get('/hello', MyController::class);En este ejemplo, cuando se hace una solicitud a /hello, Laravel invoca el método __invoke de MyController.
Laravel sigue soportando este patrón en versiones recientes como Laravel 11, ya que es una técnica conveniente y elegante para manejar rutas o middleware de una sola acción.
php artisan make:view \_test/create
Para crear una vista utilizamos esta nomenclatura si queremos meterlo o crear un directorio, ponemos le nombre del directorio seguido del nombre de la vista.
NOTA: utilizar el nombre de la vista con el nombre del método nos ayudará a tener mejor organizado todo
public function show($id)
{
return view(
'_test.show',
['id' => $id]
);
}
esto de aqui es igual a esto
public function show($id)
{
return view('_test.show',compact($id));
}El capitulo 05 explica los componentes
php artisan make:component <nombre componente>
Esto lo que hace es crear 2 archivos por un lado el componente en resources/views/components para ser reutilizado y por otro lado en App/View/Components para poder crear un clase que maneje dicho controlador
Para llamar a un componente desde una plantilla blade utilziamos la zintaxis (desde Blade 11) ejemplo
<x-alert type="info" title="¡Error!" subtitle="Algo salió mal. Por favor, intenta de nuevo.">
</x-alert>
e indicamos los atributos
La expresión que mencionas:
class="alert {{ $attributes->merge(['class' => $alertClass]) }}"es utilizada en Laravel Blade para asignar dinámicamente clases CSS a un elemento HTML. Vamos a desglosarla:
-
class="alert":
Esta parte establece una clase CSS fija, en este caso,alert, que siempre estará presente en el elemento HTML. -
{{ ... }}:
Los dobles corchetes{{ }}son utilizados en Blade para imprimir el valor de una variable o una expresión PHP dentro del HTML. Todo lo que está dentro de los corchetes se evalúa y se inserta en el lugar correspondiente. -
$attributes->merge(['class' => $alertClass]):$attributes: Es una variable especial disponible en los componentes de Blade que contiene todos los atributos HTML adicionales que puedan pasarse al componente cuando se llama.merge(['class' => $alertClass]): Esta función combina cualquier clase adicional que se pase a través de$attributescon la clase dinámicaalertClass, que normalmente depende de alguna lógica en la clase del componente.
Supongamos que tienes un componente Alert que espera un tipo de mensaje (danger, warning, success, etc.) y, en base a eso, define una clase CSS específica:
alert.blade.php:
<div class="alert {{ $attributes->merge(['class' => $alertClass]) }}">
{{ $slot }}
</div>Luego, cuando llames al componente en una vista, podrías hacerlo así:
<x-alert type="danger" class="extra-class">
Este es un mensaje de peligro.
</x-alert>$alertClass: Podría ser algo comoalert-danger, dependiendo del valor detypeen el componente.$attributes->merge(['class' => $alertClass]): Combinaextra-class(pasada en el llamado) conalert-danger, resultando en algo comoalert alert-danger extra-class.
El HTML generado sería algo como:
<div class="alert alert-danger extra-class">Este es un mensaje de peligro.</div>Esto permite que las clases CSS sean flexibles y se puedan combinar de manera dinámica según el contexto en el que se utilice el componente.
Creamos una plantilla y ponemos esta etiqueta para decirle que el contenido es variable
@yield('content')Desde la vista extendemos
@extends('layouts.nombre-plantilla)y para meter contenido en la plantilla deberemos llamar a la directiva
@section('content)
contenido que será renderizado en la plantilla
@endsection// Ejecuta las migraciones
php artisan migrate
// Deshace migraciones
php artisan migrate:rollback
// Hace todos los down y luego todos los up de las migraciones, pero es un método destructivo porque elimina los registros
php artisan migration:refresh
// Para crear tablas. te genera la estructura base para crear una tabla
php artisan make:migration create\_<nombre_migracion>\_table
// Crear migración
php artisan make:migration <nombre_migracion>
// Craar update de una migración
php artisan make:migration add*<nombre>\_to*<nombretbla>\_table
// Ejemplo
php artisan make:migration add_new_to_sys_items_table
Esta forma no es agresiva ya que no elimina datos
// Crear Modelo
php artisan make:model Items
Conveciones de modelos:
Los modelos deben ser en singular y la tabla de la DB en plural asi no hará falta crear la variable
protected $table=<nombretabla> porque tomará como base el nombre y el plural en la base de datos, ejemplo
Si tenemos una tabla llamada sys_items y el modelo se llama SysItem no hará falta indicar la tabla pero por ejemplo si hacemos lo mismo con la tabla sys_familys, dará un error porque ELOQUENT/LARAVEL buscará la tabla sys_families
Route::get('/prueba', function () {
$fam = SysItem::find(1);
$fam->title = 'Prueba3333';
//$fam->type = 'Casetas';
$fam->active = 1;
$fam->save();
return $fam;
});Esto es para normalizar, prevenir y validar los datos de entrada en los formularios
protected function title(): Attribute
{
return Attribute::make(
// Mutador
set: fn($value) => strtoupper($value),
// Accesor
get: fn($value) => (
strtolower($value) . 'hola'
),
);
// return Attribute::make(
// set: function($value){
// return strtoupper($value);
// }
// );
}
protected function description(): Attribute
{
return Attribute::make(
set: fn($value) => strtolower($value),
);Están dentro de la carpeta /database.
Sirve para insertar datos de ejemplo o sistema de datos base
// Ejecutar los seeder
php artisan db:seed
// Elimina/Crea las tablas y ejecuta los seeders
php artisan migrate:fresh -- seed
// Para crear un SEEDER debemos hacer
php artisan make:seeder <NombreSeeder>
php artisan make:seeder FamilysSeed
Están dentro de la carpeta /database y sirve para crear datos de ejemplo
// Crear un seeder
php artisan make:factory <NombremodeloFactory>
Y esto se pone en el seeder pra ejecutarlo
SysFamily::factory(10)->create();
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\SysFamily>
*/
class SysFamilyFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
//
'title' => $this->faker->sentence(),
'type' => $this->faker->randomElement(['Casetas', 'Jardinería', 'Maquinaria']),
'active' => $this->faker->randomElement([1, 0]),
];
}
}El comando php artisan route:list o php artisan r:l --> Lo que hace es listar todas las rutas que tenemos definidas en nuestro archivo La ruta resource lo que hace es crear el listado de rutas en 1 sola linea, por ejemplo todas estas lineas de rutas puedes ser sustituidas por una sola Ejemplo:
// Familias
Route::get('/familias/listar', [FamilyController::class, 'index'])->name('familys.list');
Route::get('/familias/detalles/{id}', [FamilyController::class, 'show'])->name('familys.details');
Route::get('/familias/crear', [FamilyController::class, 'create'])->name('familys.create');
Route::post('/familias/crear', [FamilyController::class, 'store'])->name('familys.store');
Route::get('/familias/editar/{id}', [FamilyController::class, 'edit'])->name('familys.edit');
Route::post('/familias/editar/{id}', [FamilyController::class, 'update'])->name('familys.update');
Route::get('/familias/eliminar/{id}', [FamilyController::class, 'delete'])->name('familys.delete');Route::resource ('familias',FamilyController::class);Esto creará todas las rutas, pero sino queremos que no se cree alguna ruta tan solo debemos añadir esto
Route::resource ('familias',FamilyController::class)->except(['destroy','edit']);O solo querememos que nos cree unas en especifico
Route::resource ('familias',FamilyController::class)->only(['create','update']);Hay un total de 7 rutas para hacer el CRUD
Además podemos ver con que nombre se nombrarán nuestras rutas.
Route::resource ('familias',FamilyController::class)->only(['create','update'])->names('post');También puedo especificar parametros en esta ruta de recurso
Route::resource('familias',FamilyController::class)
->only(['create','update'])
->parameters(['familia'=>'family'])
->names('post');Esto lo que hace es cambiar el nomnbre del parametro a recibir de familias por family
En cuanto a las rutas de API tan solo tienen 5 métodos de CRUD
Route::apiResource('familias',FamilyController::class)Las rutas de modelo lo que hace es simplificar el código en blade podemos ir a un registro de la siguiente manera
// Tan solo indicando el objecto $post, LARAVEL ya sabe que debe utilizar la ID no hace falta poner $post->id
{{ route('familys.edit',$post) }}En cuanto al controlador hacemos un cambio para ahorrar 1 linea pasamos de esto
public function show($id)
{
$family = SysFamily::find($id);
return response()->json($family);
}a
public function show(SysFamily $id)
{
//$family = SysFamily::find($id);
return response()->json($family);
}Indicando solo en el controlador el Modelo a utilizar, y ya sabe LARAVEL que debe utilizar ID
Ahora bien, si queremos que se utilice otro tipo de valor que no sea el ID deberemos ir al método y crear un método public para decile que utilice otro valor
public function getRouteKeyName(){
return 'slug';
} $family = new SysFamily();
$family->title = $request->title;
$family->type = $request->type;
$family->active = $request->active;
$family->save();esto podriamos conseguir poner asi
Sysamily::create([
$family->title = $request->title;
$family->type = $request->type;
$family->active = $request->active;
]);y esto otro podriamos resumirlo a, pero esto es alo inseguro porque pueden editarnos el formulario y meterse mal todo.
SysFamily::create($request->all());Para evitar eso debemos hacer esto, deberemos ir al controlador y crear una propiedad protegida con los nombres los campos que podrán usarse para asignación masiva
protected $fillable = ['title', 'type', 'description', 'active'];También podemos hacer lo contrario, podemos poner que campos NO queremos que se guarden
protected $guarded = ['active'];Si queremos usar asignación masiva en el método update podremos hacerlo de la siguiente manera
$sysFamily->update($request->all);Las validaciones de las entradas de formulario se deben hacer en el método store, y es asi
// Validaciones en la creación
public function store (Request $request){
$errors = $request->validate([
'title' => 'required|min:5|max:10', // Forma más corriente
'slug' => ['required','min:5','max:10'], // Forma más compleja
'token' => 'required|unique:SysFamily',
]);
}
// Validaciones en la edición
public function edit (Request $request){
$errors = $request->validate([
'title' => 'required|min:5|max:10', // Forma más corriente
'slug' => ['required','min:5','max:10'], // Forma más compleja
'token' => 'required|unique:SysFamily,token,{$family->id}', // Con esto conseguimos que excluya el registro que estamos editando
]);
}Además en la plantilla de Blade podemos agregar un div que nos muestre los errores del formulario
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endifAdemás para no perder los datos que no se han validado en ese formulario en el campo debemos poner en el campo value esto
{{old('title')}}Nota si queremos hacerlo en el formulario de edición debemos hacerlo asi para actualizar los cambios
{{old('title',$family->title)}}Para mostrar el mensaje debajo del campo usamos esto
<form action="{{ route('ruta.de.envio') }}" method="POST">
@csrf
<!-- Campo para el nombre -->
<div class="form-group">
<label for="name">Nombre</label>
<input type="text" name="name" class="form-control @error('name') is-invalid @enderror" value="{{ old('name') }}">
<!-- Mostrar el error del campo "name" -->
@error('name')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
</form>Para ver todas las reglas de validación podemos ir a: https://laravel.com/docs/11.x/validation#available-validation-rules
'php artisan make:request ` esto creará el archivo dentro de App\Http\Request
Para ello en nuestro controlador deberemos llamar al objecto Family deberemos hacerlo a StoreFamilyRequest que hará la validación previa
Revisar este video: https://www.youtube.com/watch?v=CnsaIC9JR4Q&list=PLZ2ovOgdI-kVtF2yQ2kiZetWWTmOQoUSG&index=22
Usaremos el paquete: https://laravel-lang.com/basic-usage.html#installation