Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Introduccin a Laravel
Laravel es uno de los frameworks ms fciles de aprender para PHP, yo dira que
tan fcil como Codeigniter. Sin embargo en Laravel, fcil no quiere decir simple. Este
potente framework combina los features ms modernos de PHP para brindarnos una
interfaz elegante y hasta divertida de usar:
Quieren una ruta?
Cdigo:
// En app/routes.php:
Route::get(welcome, function() {
return Bienvenidos a Laravel;
});
@stop
Y ahora creamos nuestro Layout
Cdigo:
<!-- En app/views/layout.blade.php -->
<!doctype html>
<html>
<head>
<title>Hacer vistas en Laravel es muy sencillo</title>
</head>
<body>
@yield(content)
</body>
</html>
Cuando usemos nuestra vista "welcome", Laravel cargar automticamente la
vista layout por nosotros, y reemplazar en la plantilla layout la lnea @yield('content') por
todo el HTML que hayamos escrito en la plantilla welcome entre @section('content') y
stop, quedando el resultado as:
Cdigo:
<!doctype html>
<html>
<head>
<title>Hacer vistas en Laravel es muy sencillo</title>
</head>
<body>
<h1>Bienvenidos a Laravel</h1>
</body>
</html>
De esta forma tendremos 1 solo layout que usaremos en todas nuestras vistas,
evitando repetir el cdigo.
Ahora usar nuestras vistas es tan fcil como esto:
Cdigo:
Route::get(welcome, function() {
return View::make(welcome);
});
Qu tal si quisiramos pasar parmetros dinmicos a nuestra vista? Tan fcil como
esto:
Cdigo:
View::make(welcome)->with(name, Duilio);
cristalab.com/tutoriales/introduccion-a-laravel-c111339l/
En vez de:
Cdigo:
cristalab.com/tutoriales.php?id=c111339I.
Estas son tiles para los motores de bsqueda y tambin para los usuarios. En
otro tutorial hablaremos de esto.
Tambin necesitarn un conocimiento bsico de PHP, es un plus si saben de
programacin orientada a objetos o si ya han usado otros frameworks. Igual tratar de
explicar todo detalladamente y adems tenemos la seccin de comentarios donde pueden
hacer preguntas, con suerte adems de m, otros usuarios tambin quieran ayudar a
aclarar dudas.
Cmo instalar Laravel y Composer
Si tienen experiencia con PHP sabrn que ste es un lenguaje interpretado,
bsicamente una library para PHP (un framework por ej.) no es ms que una serie de
archivos .php dentro de carpetas dentro de sub-carpetas, y para instalarlo por lo general
no hace falta ms que descargar archivos de un repositorio GIT o de una pgina,
descomprimirlos en algn lado y listo.
Para instalar Laravel 4, hace falta un paso extra. Pero no nos preocupemos, en
realidad es una ventaja que nos pondr no slo a Laravel sino a miles de paquetes a
nuestra disposicin, me refiero a Composer.
Composer
Composer es un excelente manejador de paquetes y dependencias entre paquetes
para PHP.
ir
buscando
instalando
cada
paquete
las
Tambin les har falta una consola de GIT, yo uso sta. Mismo proceso:
descarguen, ejecuten, siguiente, siguiente, finalizar.
Instalar Laravel
Una vez instalado composer, usando la consola/terminal (si estamos en Windows
usaremos la consola de GIT que recien instalamos), vamos a nuestra carpeta de
proyectos,
por
ejemplo:
cd
/var/www
/home/usuario/proyectos_web/
Todo lo cual lleva el desarrollo de PHP a otro nivel, donde nosotros, los
programadores podemos aprovechar el trabajo de otros y fcilmente poner parte de
nuestro trabajo al alcance de otros, en vez de seguir reinventando la rueda una y otra vez.
Pero volviendo a la instalacin de Laravel...
Una vez que se complete la descarga de los paquetes, verificamos nuestro
directorio, el cual debe lucir similar a ste:
http://localhost/laravelpruebas/public
Directorio pblico:
(Es importante acceder a la carpeta /public que es la puerta de nuestro proyecto para la
web, ms adelante veremos esto en detalle)
Y si todo ha salido bien:
Si leste you have arrived en tu navegador, ests listo para la tercera parte, sino
tienes varios das, los comentarios de abajo y Google para investigar qu sali mal y
prepararte para la siguiente entrega, donde explicar lo que contienen las carpetas y
archivos instalados por Composer, entre otros temas.
Stay tuned
Si estamos trabajando con MySQL, como es mi caso, dejaremos la lnea intacta, sino
editaremos el valor entre comillas a sqlite, pgsql, etc. segn sea el caso.
Entre las bases de datos soportadas por defecto en Laravel encontramos: MySQL, SQL
Lite, PostgreSQL y SQL Server.
3 - Usamos PHPMyAdmin o cualquier otra herramienta de nuestra preferencia para crear
la base de datos, en mi caso, con PHPMyAdmin y MySQL crear una DB llamada
pruebalaravel:
Cdigo:
CREATE DATABASE `pruebalaravel` ;
'driver'
=> 'mysql',
'host'
=> 'localhost',
=> '',
),
Por ejemplo:
1. Inicialmente crearemos una tabla llamada users.
2. En unas semanas necesitaremos otra tabla llamada tasks.
3. Luego agregaremos un campo adicional llamado role en la tabla users para dividir los
administradores de los usuarios normales.
Cada uno de estos pasos implicar crear una migracin diferente con la que el framework
sabr cmo modificar la base de datos, tanto hacia el nuevo esquema (del paso 1 al paso
2) como al esquema anterior (por ejemplo: de vuelta al paso 2 desde el paso 3).
Ahora veamos:
Cmo instalar el sistema de migraciones en Laravel
Abrimos nuestra consola o terminal (recuerden usar la consola instalada por GIT si usan
Windows) y tipeamos lo siguiente:
Cdigo:
php artisan migrate:install
(Sino recibes este mensaje, vuelve al punto anterior sobre configurar la base de datos y
revisa que todo est bien)
Tabla de migracin creada con xito?
S, si vuelves a tu herramienta de base de datos (ej. PHPMyAdmin) vers la siguiente
tabla:
Esta es una sencilla tabla que usa Laravel para conocer el estado de la migracin en tu
servidor, por ahora est vaca.
Siguiente paso:
Crear nuestra primera migracin con Artisan y Laravel
Para ello ejecutamos el siguiente comando:
Cdigo:
php artisan migrate:make create_user_table
El primer mensaje (migracin creada) nos indica que fue creado el archivo donde
vamos a:
Crear el esquema de nuestra tabla usando el Schema Builder
Abrimos el archivo localizado en:
Cdigo:
app/database/migrations/2013_09_03_211545_create_user_table.php
//
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}
Bsicamente tenemos una clase llamada CreateUserTable y dentro tiene dos
mtodos up and down.
El mtodo up servir, en este caso, para definir nuestra tabla, reemplacemos el mtodo
vaco por lo siguiente:
Cdigo:
/**
* Run the migrations.
*
* @return void
*/
$table->string('email');
$table->string('password');
$table->string('full_name');
$table->timestamps();
});
}
Dentro
tenemos
un
llamado
al
[url=http://es.wikipedia.org/wiki/Facade_(patr%C3%B3n_de_dise%C3%B1o)]facade[/url] S
chema::create que nos permite crear el esquema de una tabla usando una interfaz de
PHP orientada a objetos, es decir, como si nuestra tabla fuera un objeto.
Schema::create acepta como primer parmetro el nombre de nuestra tabla, en este
caso: users
El segundo parmetro es una closure o funcin annima al cual se le inyecta el objeto
$table, dicho objeto nos permitir definir los campos de nuestra tabla, por ejemplo:
Cdigo:
$table->increments('id');
Le dice a Laravel que nuestra tabla tendr un campo de tipo auto incremento llamado id,
el cual es muy comn en MySQL.
Luego le decimos a Laravel que necesitamos un campo string llamado email:
Cdigo:
$table->string('email');
?
Bsicamente este mtodo le dice a Laravel que queremos crear 2 campos, uno llamado
created_at y otro updated_at ambos de tipo TIMESTAMP que servirn para saber
cuando fue creado o modificado cada uno de los registros de nuestra tabla.
Ok, Estn listos? Vamos a ejecutar la migracin: vamos de nuevo a la consola y
escribimos lo siguiente:
Cdigo:
php artisan migrate
Voil!
S que estn emocionados con nuestra nueva tabla, pero -aunque suene
doloroso- tendremos que deshacernos de ella, no se preocupen, crearemos una nueva
ms tarde y nadie notar la diferencia:
Reemplacemos el mtodo down por lo siguiente:
Cdigo:
/**
Es el fatdico mtodo que eliminar nuestra recin creada tabla users, ahora tomen valor
y escriban en la consola:
Cdigo:
php artisan migrate:rollback
No puede ser!
Rpidamente regresamos a la consola y tipeamos de nuevo:
Cdigo:
php artisan migrate
En resumen cada peticin (Request) tiene un verbo (GET, POST son los ms
comunes) y una direccin (cristalab.com/tags, laravel.com/docs, etc.). Una respuesta
(Response), por otro lado, se constituye de un cdigo (200 si todo est bien, 404 si no fue
encontrada la pgina, 500 error de server, etc.) y el cuerpo de la respuesta, que es por lo
general HTML.
Los programadores expertos dirn: Y que hay de los HEADERS? Y las
variables de sesin? No te olvides de las cookies!
Lo s, pero quera mantener esto sencillo; veamos, adems de lo que ya les
expliqu cada peticin y respuesta transporta otros datos como headers, variables de
sesin y cookies.
Por ejemplo, un header en una peticin puede tener la informacin de la IP del
usuario, en PHP prueben imprimiendo $_SERVER['REMOTE_ADDR'] o de donde
proviene
el
usuario
$_SERVER['HTTP_REFERER']
el
navegador
que
usa
$_SERVER['HTTP_USER_AGENT']
Ok pero esta informacin no es segura
Dicen los expertos y s, tienen razn, pero mantengmoslo simple por ahora.
Las variables de sesin (Session) almacenan tu informacin cuando, por ejemplo,
haces login en una pgina y se borran cuando haces logout. Si le dices a un sitio web que
recuerde tu usuario por dos semanas, probablemente eso vaya a una Cookie, que es un
pequeo archivo que se almacena en tu computador. Ms adelante veremos todo esto en
detalle.
Por ahora recuerden Solicitud = Verbo + Direccin. Respuesta = Cdigo + Texto.
Ok, comencemos a programar con Laravel
Est bien! Tranquilos. Vamos a comenzar abriendo el archivo app/routes.php Listos?.
En este archivo se manejan las rutas de Laravel. Es, digamos, la primera capa de
nuestra aplicacin.
Y qu es lo que hace una ruta?
Vern, una ruta recibe una peticin (Request) del usuario y luego de un determinado
proceso debe devolver una respuesta (Response):
Entonces esto:
Cdigo:
Route::get('/', function()
{
return View::make('hello');
});
Significa que cuando el usuario solicite (GET) la pgina de inicio ( / ) va a recibir
respuesta cdigo 200: todo bien y el HTML de la vista hello (views/hello.php).
Como ven Laravel nos brinda una interfaz elegante y sencilla para poder manejar
las solicitudes y devolver las respuestas adecuadas.
Por debajo, Laravel se apoya en el excelente componente HTTP Foundation de
Symfony2 que encapsula, mejora y normaliza todas las funcionalidades que ya trae el
lenguaje PHP para manejar requests y responses.
Obviamente nuestra aplicacin necesitar mucho ms que una pgina para funcionar,
veamos cmo hacer una segunda pgina:
Guindonos por la ruta inicial vamos a escribir otra debajo de esa, as:
Cdigo:
Route::get('cristalab', function()
{
return View::make('cristalab');
});
title="Cristalab"><img
<h1>Hello Cristalab!</h1>
</div>
Ahora escriban en el navegador http://localhost/pruebalaravel/public/cristalab
Excelente, no?
S, pero parece muy simple
Est bien, compliquemos un poco las cosas. Nuestras rutas pueden tener parmetros
que nos permitirn tener rutas dinmicas, y ms complejas, por ejemplo:
Cdigo:
Route::get('hello/{usuario}', function($usuario)
{
return "Hello $usuario";
});
Si el resultado de una ruta es una cadena de texto (string), Laravel devolver una
respuesta de tipo 200 (todo bien) y el cuerpo ser dicho texto.
Ahora en su navegador tipeen: hello/tu-nombre
Exacto! As pueden tener una URL dinmica que responda a cualquier nombre. Lo
mismo nos servira para tags, tutoriales, etc. Otro ejemplo:
Cdigo:
Route::get('tags/{tag}', function($tag)
{
return "You are browsing $tag tag";
});
Quieren limitar un parmetro a que slo sea nmeros, por ejemplo? Sencillo:
Cdigo:
Route::get('user/edit/{id}', function($id)
{
return "You are editing the user with the ID #$id";
})
->where('id', '[0-9]+');
Noten el mtodo where que se concatena a nuestra ruta y usando una expresin
regular muy simple ([0-9]+) se limita a que el parmetro id sea compuesto por uno o ms
nmeros del 0 al 9.
Tipeen user/edit/5 y recibirn el mensaje: "You are editing the user with the ID
#5". Pero si ahora tipean user/edit/laravel recibirn un error 404 dado que ni esta ni otra
ruta coincide con nuestra peticin.
Laravel nos brinda otros tipos de respuestas que analizaremos ms adelante.
Tambin veremos las rutas ms a fondo as como la creacin de controladores en un
prximo captulo.
Espero que les haya gustado. Qu opinan? Quieren que coloque ejemplos ms
avanzados o que explique todo an ms despacio? Que explique ms sobre PHP
orientado a objetos o slo Laravel? Espero leer tu opinin en los comentarios.
Stay tuned.
Cdigo:
<?php
//app/routes.php
Cdigo:
<?php
//app/controllers/ItalianController.php
protected $pastaRepo;
protected $meatRepo;
protected $sauceRepo;
$meatBalls = $this->meatRepo->cookMeatBalls();
$napoliSauce = $this->sauceRepo->cookNapoliSauce();
}
}
Interesante, no? Lamentablemente ni Laravel ni PHP pueden preparar comida por
nosotros, eso sera genial, pero si leyeron en detalle el cdigo descrito arriba y lo
entienden han dado un gran paso para ser buenos chefs, quiero decir, programadores en
Laravel.
Examinemos el cdigo:
Cmo darle nombre a una ruta y enlazarla a un controlador
Cdigo:
Route::get('pasta-with-meatballs/{id_table}/{type}', array('as' => 'pasta_meatballs', 'uses'
=> 'ItalianController@pastaWithMeatBalls'))->where(id_table, [0-9]+);
Fjense que ya el segundo parmetro no es una funcin annima, como en los ejemplos
anteriores.
Ahora es un array:
El parmetro as define el nombre de la ruta, suponiendo que escribimos nuestra
vista views/menu.blade.php podremos colocar el enlace a nuestra ruta as:
Cdigo:
<!-- app/views/menu.blade.php -->
<ul>
<li><a href={{ route(pasta_meatballs, array($idTable, long)) }}>Pasta larga</a></li>
<li><a href={{ route(pasta_meatballs, array($idTable, short)) }}>Pasta corta</a></li>
</ul>
O un redirect:
Cdigo:
Redirect::route(pasta_meatballs)
El nombre de la ruta NO es la URL De hecho, ms adelante podramos cambiar la
URL a pasta-con-albondigas y el men y el Redirect seguirn funcionando como si nada.
Bastante til.
El parmetro usesdefine el controlador y la accin que se van a usar ,
separados por una arroba:
Cdigo:
'ItalianController@pastaWithMeatBalls'
}
Un constructor es un mtodo especial de PHP que se llama cada vez que creamos un
objeto
Pero de dnde salen esos parmetros $pasta, $meat, $sauce?
Laravel los crea y asigna por nosotros automticamente!, siempre que las
interfaces existan y haya al menos una clase que implemente dicha interfaz. Lo nico que
necesitamos hacer es decirle a Laravel qu clases van a ser usadas por cada interfaz:
Cdigo:
// al final de app/start/globals.php agregaramos lo siguiente:
App::bind(PastaRepoInterface, PastaRepo);
App::bind(MeatRepoInterface, MeatRepo);
App::bind(SauceRepoInterface, SauceRepo);
En nuestra carpeta app/models/
podemos programar
los repositorios y
interfaz,
es
como
un
contrato
que
permite
definir
los
mtodos
(funcionalidades) mnimos que una clase debe tener. En s NO implementa cdigo, slo
sirve para definir los requerimientos de las clases de cierto tipo. En nuestro ejemplo,
los requisitos mnimos que nuestro restaurante exige para contratar a un chef de pasta,
seran:
Cdigo:
// app/models/PastaRepoInterface
interface PastaRepoInterface {
}
Debe saber cmo preparar espagueti, rigatonis, y lasaa, why not?
Ahora si queremos crear un chef encargado de proveerle pasta a las cocinas
escribiramos lo siguiente:
Cdigo:
// app/models/PastaRepo
class PastaRepo implements PastaRepoInterface {
public function cookSpaguetti()
{
return Pasta::where(type, =, spaguetti)->get();
}
public function cookRigatoni()
{
return Pasta::where(type, =, rigatoni)->get();
}
// Etc. Etc...
}
PastaRepoInterface es el contrato. PastaRepo es el chef que conoce las recetas.
que
el
nuevo
la
interfaz PastaRepoInterface nuestra cocina seguir funcionando sin ningn tipo de cambio
adicional. Genial No?
Por cierto, las recetas en este caso seran la lgica de nuestra aplicacin o lgica de
negocios. En este caso todas las hemos puesto dentro de nuestra carpeta de modelos,
como debe ser.
Vistas o Capa de Presentacin
Una vez que el controlador ItalianController obtiene toda la comida necesaria para crear
nuestra pasta con albndigas:
Cdigo:
$food = compact(pasta, meatBalls, napoliSauce);
Cdigo:
return Response::json($food);
De una manera muy sencilla le decimos a Laravel que redirija la peticin del
usuario de nuevo a su mesa, donde le pediremos que por favor elija pasta corta o larga.
Por supuesto necesitaramos definir otra ruta:
Cdigo:
//app/routes.php
// [More code here]
Route::get(table/{id}, array(as => table, uses => tableController@index))->where(id,
[0-9]+); //etc
Conclusin
En este captulo y con un ejemplo sencillo aprendimos qu son los controladores,
cmo se crean y usan en Laravel, tambin aprendimos cmo enlazar las rutas a ellos y
aprendimos sobre Repositorios e Interfaces que mantienen la lgica y responsabilidades
de nuestra aplicacin separadas, como debe ser. Tambin le dimos un vistazo a cmo
trabajar con vistas, redirecciones y JSON.
En los prximos captulos ir detallando todo lo anterior.
Como ltima nota, quizs algunos lectores estn pensando algo como: Pero yo no
necesito un restaurante o aplicacin tan elegante. Yo hago pginas web mssencillas.
Con Laravel podramos hacer esto:
Cdigo:
// app/routes.php
Route::get(pasta-with-meatballs, function () {
$pasta = Pasta::where(type, =, short)->get();
// Etc. Etc.
return View::make(dish, array($pasta));
});
Para qu crear un controlador y luego una intefaz y un repositorio y etc. etc. si se puede
hacer todo tan rpido y fcil?
Tienen razn, eso tambin funciona, como uno de esos puestos de comida rpida que
son atendidos por una o dos personas que te dan la bienvenida, preparan la comida, te
sirven y te cobran y limpian las mesas eso funciona. Pero si quieren ser programadores
de alta categora, lo mejor es que aprendan y usen las mejores prcticas de desarrollo en
el lenguaje y framework en el cual se desempeen... Esto es un poco de lo que quiero
lograr con Laravel y estos captulos: que aprendan Laravel pero aprendan bien.
No subestimen sus proyectos, no subestimen a sus clientes y sobretodo no se subestimen
a uds. mismos.
Como siempre todas sus impresiones, dudas, preguntas, aportes, abajo en los
comentarios, por favor
Stay tuned and happy weekend.
introduccin a Laravel,
su instalacin,
las rutas
y los controladores.
Ahora creen una ruta o controlador que llame a la plantilla (ya saben cmo, Cierto?)
En caso de que no En app/routes.php pongan esto:
Cdigo:
Route::get('template', function () {
return View::make('template');
});
<h1>Hello Cristalab</h1>
Bastante bsico, es decir, en este punto da igual si usamos Blade o no Pero, vamos a
ver:
Cmo escribir vistas dinmicas con Blade
Ok, supongamos que, como en ejemplos anteriores, queremos usar un nombre variable:
Cdigo:
Route::get('template/{name}', function ($name) {
$name = ucwords(str_replace('-', ' ', $name));
return View::make('template')->with('name', $name);
});
Ok, ahora en nuestra vista, si estuviramos usando slo PHP, tendramos que escribir
algo as:
Cdigo :
<h1>Hello <?php echo $name ?></h1>
Cdigo:
<h1>Hello {{ $name }}</h1>
Otros motores de plantillas para PHP ms avanzados como Smarty o Twig compiladores
ms poderosos, que permiten usar, por ejemplo, sintaxis de punto para los arrays, la cual
no es soportada por PHP, etc.
Cmo escribir estructuras de control con Blade
Por ltimo veremos cmo se escriben estructuras de control sencillas pero muy comunes
como IF y FOREACH.
Blade tiene una sintaxis bien simple, por ejemplo:
Cdigo:
@if ($name == 'Walter White' OR $name == 'Jesse Pinkman')
<h1>Goodbye Breaking Bad</h1>
@else
<h1>Hello {{ $name }}</h1>
@endif
Nuevamente, todo lo que est dentro del parntesis del IF es PHP comn y corriente, lo
que cambia es que en vez de escribir:
Cdigo:
<?php if (...): ?>
O:
Cdigo:
<?php if (...) { ?>
Escribimos:
Cdigo:
@if (...)
Esto es con respecto a la sintaxis, pero Blade tambin nos brinda una herramienta
potente para escribir vistas:
Uso de Layouts en Laravel con Blade
Casi todos los proyectos, por no decir todos, tienen un layout que consiste, por lo
general en un header + un footer. Por ejemplo fjense Cristalab.com Han visitado esa
pgina? Todas las pginas dentro del site cristalab.com llevan en la cabecera el logo de
Cristalab + el men etc. y en el pie de pgina tiene el men repetido y la foto de Freddier
en un pony (bueno no, pero sera ms divertido).
Ese HTML que se repite en cada pgina se llama layout y en Blade podemos escribirlo
as:
Creen una vista llamada:
Cdigo:
views/layout.blade.php
@section ('content')
@stop
Pero template a su vez extiende la plantilla layout, como si fuera un objeto hijo que
extiende de un objeto padre:
Cdigo:
<!-- views/template.blade.php
@extends ('layout')
Esa etiqueta de Blade permite definir una seccin dinmica que puede ser reemplazada
en la plantilla hijo, en este caso template.blade.php usando las etiquetas:
Cdigo :
@section ('content')
@stop
En este caso el segundo parmetro de @yield sera el valor por defecto, es decir, si
abrimos en el navegador nuestra direccin:
Cdigo:
http://localhost/pruebalaravel/public/template/cristalab
Seguiremos viendo en el ttulo del mismo la frase: Aprendiendo Laravel, que es nuestro
ttulo por defecto.
Pero si cambiamos views/template.blade.php a:
Cdigo:
@extends ('layout')
@section ('title') Saludos a {{ $name }} @stop
@section ('content')
<h1>Hello {{ $name }}</h1>
@stop
Entonces el ttulo ahora ser, por ejemplo: Saludos a Cristalab. Tengan en cuenta que
pueden crear tantas secciones como gusten, y que cada seccin puede tener un valor por
defecto y un valor distinto en cada sub-plantilla. Adems pueden usar variables, etc. en
cada seccin.
Para finalizar, 2 tips:
1. En HTML, como ya deben saber, los comentarios se escriben as:
Cdigo:
<!-- comentario -->
Y suelen ser tiles cuando el HTML que escribimos es muy complicado, sin embargo
dichos comentarios se envan al navegador junto con el resto de las etiquetas, y esto no
es siempre lo que queremos, dado que cualquiera podra leerlos y hacen el HTML un
poco ms pesado, etc
Con Blade podemos escribir comentarios as:
Cdigo:
{{-- Esto es un comentario --}}
Cdigo:
<?php $user = Auth::user() ?>
Es posible usar PHP plano dentro de Blade, slo traten de mantener sus plantillas lo ms
limpias posibles, limiten el uso de PHP, y si en tal caso lo necesitan, escriban slo
sentencias sencillas y preferiblemente al inicio de la plantilla.
Visiten la documentacin oficial para obtener ms ejemplos sobre Blade
Espero les haya gustado este tutorial, recuerden que todo esto se ir profundizando ms
adelante, por ahora es slo un bosquejo para que se familiaricen con todos estos
conceptos
Stay tuned.
Segunda parte:
Tutorial, pas a paso, de cmo escribir un mdulo CRUD con Laravel.
Actualizar y Borrar (lo que se conoce como CRUD por las siglas en ingles: Create, Red,
Update, Delete)
Vamos a crear entonces todo lo que necesitamos del controlador y las rutas en 2
pasos:
Cdigo:
Route::resource('admin/users', 'Admin_UsersController');
Esto es lo nico que hace falta para vincular el Resource Controller a nuestras rutas.
Esto generar un nuevo controlador con los mtodos necesarios para nuestro mdulo.
Vayan
app/controllers
vern
un
nuevo
archivo
llamado Admin_UsersController.php
Un ltimo paso importante: Creen una carpeta llamada admin/ dentro de
app/controllers, renombren el archivo a UsersController.php y colquenlo dentro de la
carpeta admin/ de modo que quede as:
Cdigo:
app/controllers/admin/UsersController.php
que
escribimos
antes,
funcione.
Ahora
/**
* Show the form for creating a new resource.
*
* @return Response
*/
si
abrimos
el
archivo
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($id)
{
//
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
//
}
}
Como ven tenemos ya definidos todos los mtodos para nuestro CRUD, aunque por los
momentos no hacen nada (si acceden en el navegador a /admin/users vern una pantalla
en blanco). Sin embargo, podemos revisar que los mtodos funcionan si retornamos un
string en algunos de ellos, ademas veamos las rutas a las que estn asignados:
A index se accede mediante /admin/users:
Cdigo:
public function index()
{
return 'Esta es la lista de usuarios';
}
A create se accede mediante /admin/users/create
Cdigo:
public function create()
{
return 'Aqui va el form para crear un usuario';
}
A show se accede mediante la URL del recurso + el ID numrico de algn registro, en
este caso no tenemos ninguno, pero para probar podemos colocar cualquier nmero, por
ejemplo: admin/users/5:
Cdigo:
public function show($id)
{
return 'Aqui mostramos la info del usuario: ' . $id;
}
As mismo, a edit se accede mediante la URL del recurso + un ID numrico + el
segmento /edit: por darles un ejemplo: admin/users/10/edit
Cdigo:
public function edit($id)
{
return 'Aqui editamos el usuario: ' . $id;
}
Como ya lo habrn notado, el nmero que colquen en la URL se pasa por
parmetro a algunos de los mtodos, en este caso show y edit, este nmero debera ser
el ID de usuarios existentes en la base de datos, esto lo veremos en las partes siguientes.
Tambin les comento que: index, create, show y edit son mtodos GET.
Recuerdan el tutorial sobre los [url=primeros pasos con Laravel[/url]? Cuando tipeamos:
Cdigo:
/admin/users/5 en el navegador, estamos diciendole al servidor: GET (Obten)
/admin/users/5
Para acceder a los mtodos restantes store, update y destroy necesitamos otros verbos /
mtodos: POST, PUT, DELETE. Para ello necesitaremos crear vistas y formularios que,
comnmente, son los que generan ese tipo de peticiones, as que esa ser la siguiente
parte que publicaremos en un par de das.
Stay tuned.
Con Bootstrap practicaremos cmo hacer un Layout en Laravel, adems de hacer que
nuestro panel se vea mejor.
Si es de su preferencia intenten seguir el tutorial usando otro framework, el procedimiento
debera ser bastante estndar.
Descargar Bootstrap
Descarguen la ltima versin de Bootstrap
Luego, dentro de esa carpeta copien la carpeta dist/ a la carpeta public de nuestro
proyecto
Por ltimo, renombren la carpeta dist/ a assets/ de manera que quede as, por ejemplo:
Cdigo:
Dentro de public/assets deberamos tener las carpetas css/ fonts/ y js/ que vienen en la
distribucin de Bootstrap. Si es as, todo bien.
Por ltimo vamos a copiar dos archivos que estn en descargas/bootstrap-3.0.0/assets/js/
Cdigo:
html5shiv.js
respond.min.js
Y vamos a pegarlos en public/assets/js
html5shiv y respond.js hacen falta para que Bootstrap sea compatible con las versiones
anteriores de Explorer
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries ->
<!--[if lt IE 9]>
<script src="../../assets/js/html5shiv.js"></script>
<script src="../../assets/js/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div id="wrap">
<div class="container">
<h1>Hello, world!</h1>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="//code.jquery.com/jquery.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script>
</body>
</html>
Qu hay que cambiarle a esto para convertirlo en un layout de Laravel?
Primero hay que utilizar lo que vimos en el tutorial anterior, para definir las secciones
(content y title por ahora est bien)
Cambien:
Cdigo:
<h1>Hello, world!</h1>
Por:
Cdigo:
@yield('content')
Y:
Cdigo:
<title>Bootstrap 101 Template</title>
Por:
Cdigo:
<title>@yield('title', 'Aprendiendo Laravel')</title>
Segundo, tenemos que corregir las llamadas a los assets (CSS, JS) de modo
que apunten al directorio correcto, para esto Laravel tiene helpers, que colocan la ruta
correcta por nosotros, y son portables, es decir, aunque cambiemos el directorio de
nuestro proyecto, o lo subamos a un server, seguirn funcionando las rutas:
Cambien:
Cdigo:
Por:
Cdigo:
<link href="{{ asset(assets/css/bootstrap.min.css) }}" rel="stylesheet" media="screen">
O an ms cort:
Cdigo:
{{ HTML::style('assets/css/bootstrap.min.css', array('media' => 'screen')) }}
Por:
Cdigo:
<script src="{{ assets(assets/js/bootstrap.min.js) }}"></script>
O mejor an:
Cdigo:
{{ HTML::script('assets/js/bootstrap.min.js') }}
Por ltimo, hagan lo mismo con las llamadas a los scripts para IE8, intentenlo ustedes:
Cdigo:
<script src="../../assets/js/html5shiv.js"></script>
<script src="../../assets/js/respond.min.js"></script>
Qu habra que hacer aqu? Debajo la respuesta (spoiler alert):
Cdigo:
{{ HTML::script(assets/js/html5shiv.js) }}
{{ HTML::script(assets/js/respond.min.js) }}
Algunas observaciones
Como sospecharn: asset(), HTML::style y HTML::script son todos helpers de
Laravel, funciones que sirven de ayuda para determinar la ruta, en el caso de asset y
adems, escribir HTML de forma ms dinmica en el caso de las funciones HTML::style y
HTML::script.
La llamada a Jquery hay que dejarla tal como est, dado que es una URL
absoluta: http://code.jquery.com/jquery.js no hay que usar los helpers de Laravel.
Fjense que todas las dems rutas parten de public/ Laravel se encargar de convertir:
Cdigo:
assets(assets/js/bootstrap.min.js)
Esto es muy conveniente. Adems me tom la libertad de cambiar todos los comentarios
HTML por comentarios de Blade (todo excepto el que sirve de IF para las versiones de IE,
ese qued igual por supuesto).
Nuestro Layout final, siguiendo todos los pasos, debera haber quedado as:
app/views/admin/layout.blade.php
Cdigo:
<!DOCTYPE html>
<html>
<head>
<title>@yield('title', 'Aprendiendo Laravel')</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{{-- Bootstrap --}}
{{ HTML::style('assets/css/bootstrap.min.css', array('media' => 'screen')) }}
{{-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --}}
<!--[if lt IE 9]>
{{ HTML::script('assets/js/html5shiv.js') }}
{{ HTML::script('assets/js/respond.min.js') }}
<![endif]-->
</head>
<body>
{{-- Wrap all page content here --}}
<div id="wrap">
{{-- Begin page content --}}
<div class="container">
@yield('content')
</div>
</div>
app/views/admin/users/list.blade.php
Recuerden que Laravel completa el resto del path por nosotros, es decir no hace falta
escribir app/views/ ni la extensin .blade.php cuando invocamos una vista
Como se dan cuenta necesitamos crear una nueva carpeta llamada users dentro de
app/views/admin dentro de ella colocaremos todas las vistas de nuestro mdulo users.
app/views/admin/users/list.blade.php
Cdigo:
@extends ('admin/layout')
@section ('content')
<h1>Lista de usuarios</h1>
@stop
Similar al ejemplo anterior cuando vimos las vistas todo lo que necesitamos fue extender
el layout principal y luego reemplazar las secciones.
Si accedemos ahora al navegador, por ejemplo, en mi caso:
Cdigo:
http://localhost/pruebalaravel/public/admin/users
Veremos el texto:
Cdigo:
Lista de Usuarios
Con algo de estilo bsico. Ms adelante all haremos nuestra lista de usuarios
dinmica
Ya con el layout preparado, en nuestro prximo tutorial aprenderemos cmo crear un
formulario con Laravel y probaremos las otras acciones de nuestro controlador
Admin_UsersController.
Dudas y preguntas en los comentarios.
Stay tuned.
<div class="form-group">
<label for="role">Tipo de Usuario</label>
<select name="role" id="role" class="form-control">
<option>Usuario</option>
<option>Admin</option>
</select>
</div>
<!-- Mas campos aqui -->
</form>
Pero a medida que necesitamos hacerlo dinmico, debemos tener en cuenta los
siguientes detalles, por ejemplo:
Si el usuario enva el formulario pero ocurre un error, deberamos mostrar el campo tal
como l lo haba llenado y no el valor anterior.
Cmo hacer para que en el select de roles quede una de las opciones (option) marcada
como seleccionada (selected).
Hacer manualmente todo eso convertira nuestro simple formulario en una
montaa de IFs y cdigo PHP casi imposible de leer y mantener. Les presentar cmo
quedar el formulario para nuestro mdulo de usuarios ya listo con Laravel, y luego
explicar el cdigo con calma, aqu vamos:
Creen un archivo llamado form.blade.php en la carpeta app/views/admin/users y
copien/peguen el siguiente contenido:
app/views/admin/users/form.blade.php
Cdigo:
@extends ('admin/layout')
@section ('content')
<h1>Crear Usuarios</h1>
<div class="row">
<div class="form-group col-md-4">
{{ Form::label('email', 'Direccin de E-mail') }}
{{ Form::text('email', null, array('placeholder' => 'Introduce tu E-mail', 'class' => 'formcontrol')) }}
</div>
<div class="form-group col-md-4">
{{ Form::label('full_name', 'Nombre completo') }}
{{ Form::text('full_name', null, array('placeholder' => 'Introduce tu nombre y apellido',
'class' => 'form-control')) }}
</div>
</div>
<div class="row">
<div class="form-group col-md-4">
{{ Form::label('password', 'Contrasea') }}
{{ Form::password('password', array('class' => 'form-control')) }}
</div>
<div class="form-group col-md-4">
{{ Form::label('password_confirmation', 'Confirmar contrasea') }}
{{ Form::password('password_confirmation', array('class' => 'form-control')) }}
</div>
</div>
{{ Form::button('Crear usuario', array('type' => 'submit', 'class' => 'btn btn-primary')) }}
{{ Form::close() }}
@stop
Adems de escribir el formulario, hay que enlazarlo desde nuestro controlador a la
vista, intenten hacerlo uds. mismos, abajo les dejar el cdigo de cualquier forma:
Cdigo:
public function create()
{
return View::make('admin/users/form');
}
Ya con esto podemos ver el formulario en nuestro navegador si tipeamos
/admin/users/create, en mi caso:
Cdigo:
http://localhost/pruebalaravel/public/admin/users/create
Cdigo:
{{ Form::open(array('route' => 'admin.users.store', 'method' => 'POST'), array('role' =>
'form')) }}
<!-- Formulario aqui -->
{{ Form::close() }}
Estos dos helpers (Form::open y Form::close) se encargan de abrir y cerrar las etiquetas
HTML del formulario, respectivamente, pero no slo eso:
Form::open:
Permite emular los mtodos PUT y DELETE (dado que los navegadores slo soportan
GET y POST).
Genera un token para proteccin anti ataques CSRF, lo cual est habilitado en Laravel 4
automticamente. Ms sobre ataques CSRF.
Entre otros.
Form::close:
Es necesario cuando en vez de Form::open usamos Form::model otro helper que veremos
dentro de poco.
Esto es lo que le dice a Laravel que apunte nuestro form a la accin store de nuestro
recurso admin.users.
Noten que el / de admin/users definido en app/routes.php necesitamos reemplazarlo por
un punto cuando usemos las funciones de rutas de Laravel como route() enlazadas a un
"Resource Controller".
Recuerden ver el HTML resultante haciendo control+U en Chrome, para ver el cdigo
fuente:
Cdigo:
<form method="POST" action="http://localhost/pruebalaravel/public/admin/users" acceptcharset="UTF-8">
<input
name="_token"
value="CrBlGF5WEwXNRreWfQ7m4JDoxbSx0ucCg8fwiBPG">
type="hidden"
Eso es lo que genera Laravel por nosotros en este caso, no slo la etiqueta form
sino un campo oculto para generar el token como expliqu ms arriba y la URL correcta
en el atributo action del form.
Definiendo los campos del formulario
Ms abajo empezamos a definir los campos:
Cdigo:
{{ Form::label('email', 'Direccin de E-mail') }}
{{ Form::text('email', null, array('placeholder' => 'Introduce tu E-mail', 'class' => 'formcontrol')) }}
Form::label
Ahora lo que sucede cuando cliquean ese botn es sorprendente. Si cliquean el botn
vern en el navegador NADA!
No regresa nada,
Solucionemos eso:
Cdigo:
public function store()
{
return Input::all();
}
Ahora cuando presionemos el botn Crear usuario recibiremos de vuelta todos
los datos de nuestro formulario en una cadena de texto en formato JSON:
Cdigo:
{"_token"
"CrBlGF5WEwXNRreWfQ7m4JDoxbSx0ucCg8fwiBPG"
"email"
Fjense que tanto la URL de inicio que invoca al mtodo index: admin/users como sta
que invoca al mtodo store son las mismas! Lo que cambia es el verbo o mtodo que se
est usando:
Cdigo:
GET admin/users -> llama a index()
POST admin/users -> llama a store()
Como pueden darse cuenta, cada vez est tomando ms forma nuestro mdulo, en el
prximo captulo avanzaremos un poco ms y aprenderemos cmo validar los datos
enviados por el usuario.
Preguntas y dudas en los comentarios.
Stay tuned.
Creamos el formulario para nuestro mdulo e hicimos una prueba de envo de datos
Adems, para hacer este tutorial es necesario que hayan completado: Configurar base de
datos y crear tablas con Laraveldado que necesitaremos una tabla users con los campos:
email, password, full_name, created_at y updated_at tal como explica dicho tutorial.
Validar los datos enviados en el formulario
Esta es una tarea tan comn que todos los frameworks incluyen clases dispuestas a
asistir al usuario en la validacin de datos. Laravel por supuesto no es la excepcin.
Volvamos a la funcin store donde quedamos anteriormente:
Cdigo:
public function store()
{
return Input::all();
}
Ac haremos todo el proceso.
Primero que nada, vamos a crear un nuevo usuario (new User)
En Laravel los registros de la base de datos se pueden manejar como objetos gracias
al ORM de Laravel: Eloquent.
S que es primera vez que les hablo de Eloquent, por lo tanto voy a mantener todo el
cdigo muy sencillo y en, digamos, posteriores tutoriales s les hablar de temas un poco
ms avanzados. La idea es que todos puedan seguir este tutorial
Dado que, como les dije, cada registro (fila de la tabla users) es manejado como si
fuera un nuevo objeto, y aqu intentamos crear un nuevo usuario, pues:
Cdigo:
$user = new User
Esto funciona slo porque Laravel viene con un modelo User.php ya predefinido en:
Cdigo:
app/models/User.php
Lo
que
haremos
continuacin
es
interactuar
con
nuestro
$user->fill($data);
// Guardamos el usuario
$user->save();
// Y Devolvemos una redireccin a la accin show para mostrar el usuario
return Redirect::route('admin.users.show', array($user->id));
}
else
{
// En caso de error regresa a la accin create con los datos y los errores
encontrados
return Redirect::route('admin.users.create')->withInput()->withErrors($user->errors);
}
}
Ahora qu?
Vamos al modelo (app/models/User.php) y agregamos lo siguiente:
Cdigo:
public $errors;
=> 'required|email|unique:users'',
if ($validator->passes())
{
return true;
}
$this->errors = $validator->errors();
return false;
}
Primero definimos una propiedad dentro del modelo User que servir para
almacenar los errores (en caso de que haya alguno), la coloqu pblica para simplificar el
ejemplo:
Cdigo:
public $errors;
As se crea un nuevo objeto almacenado en $validator que contiene toda la data y las
reglas de validacin. Ahora todo lo que hace falta es ejecutar la validacin:
Cdigo:
$validator->passes() //devuelve TRUE si la validacin pasa
Cdigo:
$validator->fails() //Mtodo pesimista, devuelve TRUE si la validacin falla
Y retornamos FALSE.
Prcticamente siempre que necesitemos validar algo con Laravel, usaremos este
mtodo, lo que cambia son las reglas que tenemos que definir.
Como pueden ver en el ejemplo anterior, las reglas se definen escribiendo un array
asociativo, donde la llave (key) es el nombre del campo, y el valor es las reglas asignadas
a ese campo separadas con barra | y si la regla necesita un parmetro adicional se define
con : y si son varios parmetros es separan por coma, as:
Cdigo:
'nombre_de_campo' => 'regla1|regla2|regla_con_parametros:parametro1,parametro2'
confirmed til para confirmar email o contrasea, exige que haya un campo con el mismo
nombre pero con el sufijo _confirmation y que ambos tengan el mismo valor (ej:
password y password_confirmation).
unique:table exige que el campo sea nico en la tabla table (til para campos como
username e e-mail).
Ms adelante veremos ms sobre la regla unique
Si quieren ver todas las reglas de validacin de Laravel vean la documentacin oficial
Penltimo paso:
Indicarle a Laravel qu campos se pueden llenar por asignacin masiva
Volviendo al controlador, cuando hacemos:
Cdigo:
$user->fill($data)
Excelente!
Para colocar los mensajes de error en espaol hay que hacer 3 pasos:
1. Cambiar en app/config/app.php la variable locale a es (actualmente tiene en).
2. Ir al directorio app/lang/ copiar la carpeta en/ y pegarla en el mismo directorio,
renombrndola a es/
3. Abrir la carpeta app/lang/es recin duplicada y traducir todos los mensajes a espaol.
Es posible que estos mensajes ya estn disponibles si buscan en Google, por ahora esto
se escapa un poco del alcance de nuestro tutorial.
Mantener los valores especificados por el usuario
El problema con esto es que aunque ya estamos mostrando la data no estamos
devolviendo los valores al usuario, aunque sea un error, el campo email debera decir
pepito
no
estar
en
blanco,
de
forma
que
el
usuario
completar pepito@gmail.com sin tener que reescribir todo de nuevo, por ejemplo.
Esto se puede resolver de forma muy simple con Laravel:
Modifiquemos nuestro mtodo create de manera que quede as:
Cdigo:
public function create()
{
// Creamos un nuevo objeto User para ser usado por el helper Form::model
pueda
nuestro
cambiar Form::open por otro helper llamado Form::model, que es muy parecido, slo
que como primer parmetro acepta un modelo, y lo dems queda igual:
Cdigo:
{{-- Reemplazamos Form::open por Form::model: --}}
{{ Form::model($user, array('route' => 'admin.users.store', 'method' => 'POST'), array('role'
=> 'form')) }}
Listo! Ahora prueben registrarse con email pepito por ltima vez, vern que no
slo se muestran los errores sino que Laravel ahora rebota los datos nuevamente al
formulario.
Excelente!
Por ltimo veamos un grfico de lo que sucede entre el usuario y el servidor
cuando el usuario pone pepito u otro email o campo no-vlido:
Esto nos ilustra las diferentes redirecciones que se llevan a cabo de manera casi
transparente.
Ahora si escriben todos los datos de forma vlida, vern cmo Laravel los
redirecciona a la vista show que por ahora slo muestra algo as:
Cdigo:
Aqui mostramos la info del usuario: 1
lo
siguiente
dentro
de app/views/admin/users/list.blade.php:
Cdigo:
<h1>Lista de usuarios</h1>
de
la
seccin
content
<th>Full name</th>
<th>Email</th>
</tr>
<tr>
<td>Cloud Strife</td>
<td>cloud@square.com</td>
</tr>
<tr>
<td>Aerith Gainsborough</td>
<td>aerith@square.com</td>
</tr>
<tr>
<td>Tifa Lockhart</td>
<td>tifa@square.com</td>
</tr>
</table>
Recuerden simplemente tipear [URL del proyecto]/public/admin/users para ver esta
vista, en mi caso es:
Cdigo:
Acceder a http://localhost/pruebalaravel/public/admin/users:
Segundo, vamos a investigar cmo se traen registro de la base de datos con Laravel
De vuelta a:
/app/controllers/admin/UsersController.php:
Cdigo:
<?php
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
return View::make('admin/users/list');
}
Vamos a reemplazar el mtodo index() por esto:
Cdigo:
public function index()
{
$users = User::all();
return View::make('admin/users/list')->with('users', $users);
}
Con el mtodo User::all(), Laravel se encarga de traernos todos los registros de la tabla
de usuarios por nosotros.
Aunque es posible escribir sentencias SQL de forma manual en Laravel, con Eloquent y el
Fluent Builder de Laravel en el 90% de los casos no nos har falta.
Si desean investigar lo que devuelve el mtodo User::all pueden hacerle un dd() a la
variable $users:
Cdigo:
dd($users)
Vern
que
la
variable
contiene
un
objeto
de
Cdigo:
<table class="table table-striped">
<tr>
<th>Full name</th>
<th>Email</th>
</tr>
@foreach ($users as $user)
<tr>
<td>{{ $user->full_name }}</td>
<td>{{ $user->email }}</td>
</tr>
@endforeach
</table>
Ahora al abrir admin/users yo puedo ver el mmm nico usuario de mi tabla de
usuarios, es decir, yo mismo:
<p>
<a href="{{ route('admin.users.create') }}" class="btn btn-primary">Crear un nuevo
usuario</a>
</p>
<!-- Etc -->
Super! No queremos que nuestros usuarios se aprendan todas las URLs de nuestro
panel, Cierto?
Noten el nombre de la ruta admin.users.create.
Dentro del form (app/views/admin/users/form.blade.php) podramos colocar a un link para
regresar a la lista. La ruta sera admin.users.index. Intenten hacerla ustedes mismos.
Ahora s. Agreguen ms usuarios, al menos 5. Necesito que agreguen nuevos registros
porque vamos a aprender:
Cmo paginar filas con Laravel
Por supuesto si tenemos 5-10 hasta 20 usuarios no habra problema con mostrarlos todos
en una sola pgina, pero imaginen que se vuelven tan buenos programadores con Laravel
que los contratan para hacer un sistema con cientos de usuarios No van usar all()
para traerlos todos de golpe, hay que buscar otra opcin, y una buena es paginar los
registros.
Paginar con Laravel es increblemente fcil, es hermoso, es
Slo reemplacen all por paginate en el controlador:
Cdigo:
$users = User::paginate();
Cdigo:
{{ $users->links() }}
Guarden y ahora vamos a crear una nueva plantilla para la paginacin, todo lo que
yo hice fue tomar el archivo localizado en:
Cdigo:
vendor/laravel/framework/src/Illuminate/Pagination/views/slider.php
y modificarlo ligeramente:
app/views/pagination.php:
Cdigo:
<?php
$presenter = new Illuminate\Pagination\BootstrapPresenter($paginator);
?>
Lo nico que hice fue eliminar un div que sobraba y ponerle la clase pagination al UL, el
PHP lo dej intacto, as que no se asusten, por favor.
En la versin 3 de Laravel no se poda cambiar el HTML de la paginacin, as que haba
que modificar el CSS de Bootstrap para conseguir para que fuera compatible con el
primero
Bien, recarguemos nuestra lista (admin/users) y debera verse as:
Stay tuned.
Bonus Track: Construye t mismo la accin / vista show
Hora de probar sus nuevas habilidades con Laravel: a veces la mejor forma de aprender
es intentando hacer las cosas uno mismo, esto es lo que quiero que intenten ahora:
Crear la accin y vista show dinmicas (la ms sencilla en nuestro mdulo CRUD)
Los ayudar con algunos tips que les harn falta:
Cmo traer un registro
Traer un (1) solo registro se hace a travs de la funcin User::find($id), ejemplo:
Cdigo:
$user = User::find($id)
Esta funcin la necesitarn en los mtodos show, edit y update, que adems reciben el ID
numrico de cada registro, dicho id es el primer parmetro de User::find y permite decirle
a Laravel cual de los registros queremos obtener.
Cmo lanzar errores 404
Si el registro no es encontrado la variable $user contendr el valor NULL, si ese es el
caso deberamos abortar la operacin y lanzar un error 404, en Laravel lo ltimo se
puede hacer as:
Cdigo :
App::abort(404);
Recuerden pasar el usuario $user a la vista, y recuerden que en ella cada columna es una
propiedad del objeto, ejemplo:
Cdigo :
$user->full_name
De igual forma, sera buena idea agregar un botn a volver a la lista desde la accin
show.
Este tutorial es muy trivial, lo haremos basado en el progreso que hemos hecho hasta
ahora, copiando, no, ms bien reusando parte del cdigo que ya producimos para crear
la accin create.Primero regresemos a la lista de usuarios:
app/views/admin/users/list.blade.php
All vamos a agregar una columna adicional para agregar un botn a la accin editar
usuarios:
Cdigo:
<table class="table table-striped" style="width: 900px">
<tr>
<th>Nombre completo</th>
<th>Correo electrónico</th>
<th>Acciones</th>
</tr>
@foreach ($users as $user)
<tr>
<td>{{ $user->full_name }}</td>
<td>{{ $user->email }}</td>
<td>
<a href="{{ route('admin.users.show', $user->id) }}" class="btn btn-info">
Ver
</a>
Esto nos permitir acceder a la opcin de editar fcilmente. Ahora, de vuelta en:
app/controllers/admin/UsersController.php
Cdigo:
/**
* Show the form for editing the specified resource.
*
Si el usuario no existe se aborta la operacin con un error 404. Por ltimo se le pasa el
usuario a la vista, como ya hemos hecho antes.
Al darle clic a editar en cualquiera de sus usuarios, vern el mismo formulario usado para
crear pero con los campos llenos
A m me gusta evitar tener 2 vistas con casi el mismo HTML repetido, en este caso se
puede hacer que el mismo formulario sirva tanto para create como para edit de esta
forma:
Cdigo:
@extends ('admin/layout')
<?php
if ($user->exists):
$form_data = array('route' => array('admin.users.update', $user->id), 'method' =>
'PATCH');
$action
= 'Editar';
else:
$form_data = array('route' => 'admin.users.store', 'method' => 'POST');
$action
= 'Crear';
endif;
?>
@section ('content')
<p>
<a href="{{ route('admin.users.index') }}" class="btn btn-info">Lista de usuarios</a>
</p>
<div class="row">
<div class="form-group col-md-4">
{{ Form::label('email', 'Direccin de E-mail') }}
{{ Form::text('email', null, array('placeholder' => 'Introduce tu E-mail', 'class' => 'formcontrol')) }}
</div>
<div class="form-group col-md-4">
{{ Form::close() }}
@stop
En las primeras lneas definimos el ttulo Crear o Editar y la ruta y mtodo que se le va
a pasar al form, dependiendo si el usuario existe o no.
Tambin se puede lograr lo mismo pasando la data desde el controlador a la vista:
Cdigo:
public function edit($id)
{
$user = User::find($id);
if (is_null ($user))
{
App::abort(404);
}
= 'Editar';
Redirect::route('admin.users.edit',
$user->id)->withInput()-
>withErrors($user->errors);
}
}
Con esto ya debera funcionar a medias la funcin de actualizar, sin embargo, si intento
actualizar mi propio usuario recibo un error:
Cdigo:
El email ya ha sido utilizado
Esto es por la regla unique definida en app/models/User.php, adems que editar la clave
debera ser opcional.
Corrijamos el mtodo isValid:
Cdigo:
public function isValid($data)
{
$rules = array(
'email'
=> 'required|email|unique:users',
// Si el usuario existe:
if ($this->exists)
{
//Evitamos que la regla unique tome en cuenta el email del usuario actual
$rules['email'] .= ',email,' . $this->id;
}
else // Si no existe...
{
// La clave es obligatoria:
$rules['password'] .= '|required';
}
if ($validator->passes())
{
return true;
}
$this->errors = $validator->errors();
return false;
}
Cada vez que se intenta acceder a un atributo, Laravel intenta ver si el modelo tiene un
mtodo llamado get[nombre del atributo en camelCase]Attribute, as mismo cada vez que
se intenta guardar un atributo dentro del modelo, se intenta llamar set[nombre del atributo
en camelCase]Attribute, que permiten modificar el comportamiento por defecto. No me
creen? Agreguen lo siguiente al modelo, temporalmente:
Cdigo:
public function getFullNameAttribute()
{
return strtoupper($this->attributes['full_name']);
}
Ahora todos, todos, TODOS los atributos full_name de todos los usuarios se imprimirn
siempre
en
maysculas,
al
menos
que
borremos
cambiemos
el
mtodo
getFullNameAttribute.
Eloquent tiene muchos mtodos interesantes que se escapan, lamentablemente, del
alcance de este tutorial
Parece mucho cdigo, adems hay el mismo cdigo repetido en store y update, Cierto?
Que tal si en el modelo (app/models/User.php) agregamos un nuevo mtodo:
Cdigo:
public function validAndSave($data)
{
// Revisamos si la data es vlida
if ($this->isValid($data))
{
// Si la data es valida se la asignamos al usuario
$this->fill($data);
// Guardamos el usuario
$this->save();
return true;
}
return false;
}
Cdigo:
// Revisamos si la data es vlida y guardamos en ese caso
if ($user->validAndSave($data))
{
// Y Devolvemos una redireccin a la accin show para mostrar el usuario
return Redirect::route('admin.users.show', array($user->id));
}
else
{
// En caso de error regresa a la accin create con los datos y los errores
encontrados
return
Redirect::route('admin.users.edit',
$user->id)->withInput()-
>withErrors($user->errors);
}
Esta es la ltima entrega sobre la serie cmo crear un mdulo CRUD de usuarios, y en
este ltimo captulo veremos cmo borrar un registro con Laravel, adems usaremos
jQuery
AJAX.
Crear un formulario
Editar registros
Para hacer ms sencillo este tutorial y en general casi cualquier problema, vamos a
separar el proceso por partes. Primero vamos a aprender cmo borrar un registro sin
AJAX.
En
nuestro
formulario
de
usuarios
vamos
colocar
lo
siguiente:
app/view/admin/users/form.blade.php
Cdigo:
@if ($action == 'Editar')
{{ Form::model($user, array('route' => array('admin.users.destroy', $user->id), 'method' =>
'DELETE', 'role' => 'form')) }}
<div class="row">
<div class="form-group col-md-4">
{{ Form::submit('Eliminar usuario', array('class' => 'btn btn-danger')) }}
</div>
</div>
{{ Form::close() }}
@endif
Fjense que como yo uso la misma plantilla para crear y para editar debo agregar
el @if para que la opcin de eliminar se muestre slo si el usuario est trabajando sobre
un registro existente.
El resto es similar a lo que ya hemos visto. Slo que para construir la ruta se
usa admin.users.destroy (destroy no delete) y el mtodo es DELETE en vez de POST o
PATCH.
Tambin les he comentado que los navegadores no soportan sino los mtodos GET y
POST, pero Laravel y otros frameworks como Symfony (en realidad la idea viene de
Symfony) emulan estos mtodos usando un campo oculto _method por ejemplo. Siempre
pueden ver cdigo fuente (control + u en Chrome) para ver qu les generan los helper del
framework que estn usando.
Al
hacer
click
sobre
este
botn
no
vern
nada.
Pero
si
vamos
al
Entonces al cliquear eliminar vern un mensaje. Eso quiere decir que ya nuestra vista
funciona. Ahora veamos cmo hacer para que el registro se borre realmente.
Hay 2 formas:
Cdigo:
public function destroy($id)
{
$user = User::find($id);
if (is_null ($user))
{
App::abort(404);
}
$user->delete();
return Redirect::route('admin.users.index');
}
Nos traemos el registro, verificamos que exista y por ltimo llamamos al mtodo delete.
La segunda es ms sencilla:
Cdigo:
public function destroy($id)
{
User::destroy($id);
return Redirect::route('admin.users.index');
}
Este mtodo ms simple slo acepta como parmetro la ID de un registro, en este caso
un usuario y borra el mismo.
A m me gusta ms el primer mtodo porque es ms orientado a objetos. Quizs adems
de borrar al usuario necesitemos borrar algunas imgenes asociadas a ste o hacer otra
operacin, en ese caso es ms conveniente el primer mtodo.
Si hacemos click en el botn eliminar seremos redireccionados a la lista pero veremos
cmo el registro seleccionado antes fue eliminado.
Agregar la opcin de eliminar a la lista
En views/admin/users/list.blade.php vamos a agregar un link que nos servir para
llamar el javascript para eliminar un registro:
Cdigo:
<a href="#" data-id="{{ $user->id }}" class="btn btn-danger btn-delete">
Eliminar
</a>
Este link lo van a agregar al lado del botn editar, de forma que quede as:
Ahora vamos a agregar al final de la misma plantilla, justo antes del @stop lo siguiente:
Cdigo:
{{ Form::open(array('route' => array('admin.users.destroy', 'USER_ID'), 'method' =>
'DELETE', 'role' => 'form', 'id' => 'form-delete')) }}
{{ Form::close() }}
Esto nos va a dar un form oculto que servir para llamar a la accin de delete como en el
ejemplo anterior, pero esta vez con javascript.
Noten que ac el ID lo dej como un texto USER_ID, luego lo reemplazar por el ID
correcto, tambin con Javascript.
Ahora vamos a crear un nuevo archivo en public/assets/js/admin.js con lo siguiente:
Cdigo:
$(window).ready(function () {
if ( $ ('.btn-delete').length)
{
$('.btn-delete').click(function () {
var id = $(this).data('id');
$(this).parents('tr').fadeOut(1000);
});
}
});
Primero
vamos
adaptar
nuestra
accin
de
eliminar
if (is_null ($user))
{
App::abort(404);
}
$user->delete();
if (Request::ajax())
{
return Response::json(array (
'success' => true,
'msg'
'id'
=> $user->id
));
}
else
{
return Redirect::route('admin.users.index');
}
}
Las primeras lneas quedan igual, pero al final vamos a decidir que si la peticin es
AJAX if
(Request::ajax()) vamos
devolver
un JSON usando
el
if ($('.btn-delete').length) {
$('.btn-delete').click(function() {
var id = $(this).data('id');
row.fadeOut(1000);
});
ste no es un tutorial de Javascript sin embargo les voy a explicar un poco qu hace el
nuevo cdigo de admin.js
Primero obtenemos el ID del registro que es muy importante, ste estaba en un atributo
data del link para eliminar colocado en la lista anteriormente:
Cdigo:
<a ... data-id="{{ $user->id }}" >
Segundo obtenemos el objeto form con Jquery, al que se le asign un ID de HTML formdelete anteriormente.
Cdigo:
{{ Form::open(array(..., 'id' => 'form-delete')) }}
Luego usando este objeto form para obtener el valor del atributo action que nos dar la
URL que tenemos que invocar para eliminar el registro, PERO recuerden que estbamos
usando un placeholder USER_ID por eso lo reemplazamos por el ID real que queremos
eliminar, obtenido previamente:
Cdigo:
var action = form.attr('action').replace('USER_ID', id);
$(this), en este caso corresponde al botn eliminar y el mtodo parents de Jquery nos
trae finalmente la fila donde se encuentra dicho botn, que es la fila (<tr>) del mismo
usuario.
Luego desaparecemos la fila usando un efecto atractivo de jQuery:
Cdigo:
row.fadeOut(1000);
Vean que:
Como primer parmetro usamos la variable action que ya tendr la URL correcta para
eliminar el registro.
Como segundo parmetro serializamos los valores del form-delete (eso nos permite
enviar los campos ocultos _method y el _csrf_token, necesarios para que la peticin a
Laravel sea vlida).
El tercer parmetro es un callback que se ejecutar una vez que la llamada al servidor
haya finalizado con xito.
El cuarto parmetro le dice a Jquery que esperamos que la data obtenida de regreso est
en formato JSON.
Este callback tiene algo de cdigo interesante que realmente no hace mucha falta, pero
quiero que vean qu se puede hacer con la informacin retornada:
Cdigo :
function(result) {
if (result.success) {
setTimeout(function() {
alert(result.msg);
row.delay(1000).remove();
}, 1000);
} else {
alert (El registro + result.id + no pudo ser eliminado);
row.show();
}
});
Podramos por ejemplo tener un escenario donde el registro no sea eliminado (por falta de
permisos o algo as), en ese caso podemos hacer que si result.success es falso, la fila
vuelva a aparecer en la lista y se muestre un mensaje de error.
Si result.success es verdadero entonces tambin podemos mostrar un mensaje de xito y
eliminamos el HTML de la fila del cdigo.
Lo importante es notar que podemos usar los datos de JSON que devolvimos desde
nuestro controlador para alterar la vista, mostrar un mensaje etc.
En los prximos das publicar un ltimo tutorial con el indice de esta serie de tutoriales y
adems el cdigo final completo.
Para quienes hicieron el ejercicio anterior, aqu tienen un ejemplo de cmo podra quedar
la accin show:
Cdigo:
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
$user = User::find($id);
if (is_null($user)) App::abort(404);
Y la vista app/views/admin/users/show.blade.php:
Cdigo:
@extends ('admin/layout')
@section ('content')
<p>
<a href="{{ route('admin.users.edit', $user->id) }}" class="btn btn-primary">
Editar
</a>
</p>
@stop