Advertisement
  1. Code
  2. PHP

Desarrolla aplicaciones web desde cero con Laravel - Eloquent ORM

Scroll to top
Read Time: 23 min

Spanish (Español) translation by Steven (you can also view the original English article)

En esta miniserie de Tuts+, construiremos una aplicación web desde cero, mientras nos sumergimos en un nuevo framework de PHP que está cogiendo rápidamente vapor, llamado Laravel.

En esta lección, trabajaremos en una parte integral de cualquier aplicación web: los modelos. En el camino, aprenderemos sobre la increíble implementación de ORM de Laravel: Eloquent.


Revisión

¡Bienvenido de nuevo a nuestra serie de aplicaciones web desde cero con Laravel! En el primer tutorial de la serie, aprendimos mucho sobre Laravel y su filosofía:

  • Qué es Laravel
  • Lo que diferencia a Laravel de otros frameworks PHP
  • Dónde descargar Laravel
  • Cómo configurar Laravel
  • Cómo funciona el sistema de rutas de Laravel
  • Algunas otras características del sistema de rutas de Laravel
  • Cómo crear tu primer controlador en Laravel
  • Algunas características adicionales con los controladores de Laravel
  • Cómo crear tu primera Vista en Laravel
  • Cómo utilizar el motor de plantillas blade de Laravel

Si aún no lo has leído, deberías echar un vistazo al tutorial anterior y darle una lectura - esto hará que sea más fácil entender la filosofía detrás de Laravel y la mayor parte de lo que hablaremos en este tutorial.

En esta segunda parte de la serie Laravel, crearemos una parte crucial de nuestra aplicación web de prueba, Instapics, que es la implementación del modelo. ¡Sin más preámbulos, empecemos!


¿Qué son los "Modelos"?

Ya he hablado un poco sobre lo que son los modelos en uno de mis artículos anteriores, Zend Framework desde cero - Modelos e Integrando Doctrine ORM, así que para evitar repetirlo, escribiré la esencia de lo que escribí antes aquí. Siéntete libre de referirte al otro tutorial y leer más acerca de qué modelos están allí.

Resumen:

  • Los modelos son representaciones de la base de datos y deben estar donde reside toda la lógica de la empresa de una aplicación
  • Los controladores se comunican con los Modelos y les piden que obtengan la información que necesitan
  • Después, un controlador pasa esta información a la vista y se muestra
  • Es muy raro que un modelo interactúe directamente con una vista, pero a veces puede suceder cuando es necesario
  • Los modelos pueden hablar con otros modelos y no son autónomos. Tienen relaciones que se entrelazan entre sí
  • Estas relaciones hacen que sea más fácil y rápido para un Controlador obtener información, ya que no tiene que interactuar con diferentes Modelos - los Modelos pueden hacerlo entre ellos

Los modelos en Laravel, o en la mayoría de los frameworks, se desarrollan de la misma manera. La diferencia es que Laravel nos da una manera fácil de construir estos modelos, proporcionándonos métodos de uso general que la mayoría de los modelos necesitarían - el Eloquent de ORM.


El Eloquent de ORM

Un ORM es un mapeador relacional de objetos, ¡y Laravel tiene uno que te encantará! Se denomina "Eloquent", porque te permite trabajar con tus objetos de base de datos y las relaciones mediante una sintaxis elocuente y expresiva.

Eloquent ORM es la implementación ORM integrada de Laravel. En mi opinión, es una de las mejores implementaciones de ORM que he visto hasta ahora- rivalizando incluso con Doctrine ORM. Es increíblemente elegante, haciendo uso de las convenciones estándar de la industria para disminuir la configuración.

Convenciones

Por ejemplo, el uso de un modelo elocuente supone que la tabla que representa el modelo tiene un campo id. El id es la clave primaria para cualquier registro y lo utilizan la mayoría de los métodos de Eloquent.

Otra cosa que Eloquent asume correctamente es que el nombre de la tabla es la forma plural del modelo. Por ejemplo, el modelo User hará referencia a la tabla users. Como esto podría no ser siempre el estándar para algunos, Laravel proporciona una manera de invalidar esto: simplemente utiliza el indicador $table:

1
class User extends Eloquent {
2
    public static $table = 'my_users';
3
}

Esto indicará a Laravel que no use la convención y, en su lugar, use una tabla especificada.

Por último, Laravel también puede automatizar la creación y actualización de las marcas de tiempo para nosotros. Para ello, agrega una columna created_at y/o updated_at en la tabla y establece la marca $timestamp en el modelo:

1
class User extends Eloquent {
2
    public static $timestamps = true;
3
}

Eloquent verá la marca y establecerá automáticamente el campo created_at en la creación y actualizará el campo updated_at cada vez que se actualice un registro. Bastante bueno, ¿no?

Recuperación rápida

Recuperar registros es muy fácil con los métodos de recuperación de Eloquent. Por ejemplo, ¿necesitas encontrar un registro de usuario específico? Sólo haz:

1
$user = User::find($user_id);

¡Esto devuelve un modelo User en el que puedes realizar operaciones! ¿Necesitas usar condicionales? Imaginemos que deseas obtener un usuario por su dirección de correo electrónico. Para llevar a cabo esta tarea, puedes hacer algo como:

1
$user = User::where('email', '=', $email)->first();

Alternativamente, podrías utilizar los métodos dinámicos de Laravel:

1
$user = User::where_email($email)->first();

Inserciones fáciles & Actualizaciones

La inserción y actualización de modelos mediante Eloquent se puede realizar en tres pasos.

  • Paso 1 - Obtener/Crear el modelo.

    1
            $user = new User();
    
    2
            //or get an existing user
    
    
    3
            $user = User::get($user_id);
    
  • Paso 2 - Establecer los datos

    1
            $user->email = 'nikko@instapics.com';
    
    2
            $user->password = 'test1234';
    
  • Paso 3 - Guardar

    1
            $user->save();
    
  • ¡Listo!

Y finalmente, definir relaciones.

Eloquent hace que el proceso de definición de relaciones y recuperación de modelos relacionados sea simple e intuitivo.

¡Maldita sea! Eloquent admite tres tipos de relaciones:

  1. Uno a uno
  2. Uno a muchos
  3. Muchos a muchos

Para definir una relación entre modelos, deberás crear un método en ambos modelos que "describa" sus relaciones. Por ejemplo, supongamos que User has_one User_Profile. Puedes hacerlo definiendo un método user_profile en el modelo User:

1
class User extends Eloquent {
2
    public function user_profile()
3
    {
4
        return $this->has_one('User_Profile');
5
    }
6
}

Dado que User es nuestro modelo "dominante" aquí (es decir, un usuario tiene un perfil, y no un perfil tiene un usuario), definimos que User_Profile belongs_to (pertenece a un usuario) User:

1
class User_Profile extends Eloquent {
2
    public function user()
3
    {
4
        return $this->belongs_to('User');
5
    }
6
}

Una vez que hayamos definido estas relaciones, entonces podemos hacer lo siguiente:

1
/*

2
  Get the User_Profile object of a User

3
  This executes two SQL queries:

4
  

5
  SELECT * FROM `users` WHERE `id` = $user_id

6
  SELECT * FROM `user_profiles` WHERE `user_id` = $user_id

7
*/
8
$user = User::find($user_id);
9
$user_profile = $user->user_profile;
10
11
/*

12
  We can also do it the other way around

13
*/
14
$user_profile = User_Profile::where('user_id', '=', $user_id)->first();
15
$user = $user_profile->user;

Una cosa que vale la pena señalar aquí es otra convención: Eloquent asume que la clave externa utilizada en User_Profile es el nombre +_id de la tabla a la que se hace referencia. Una vez más, si deseas cambiar este comportamiento, puedes anularlo:

1
class User extends Eloquent {
2
    public function user_profile()
3
    {
4
        return $this->has_one('User_Profile', 'user_profile_user_id');
5
    }
6
}

Supongamos que queremos definir la relación entre User y Photo (sus fotos subidas). Esta es una relación de uno a muchos One-to-Many, a diferencia de la relación User Profile a User que era uno a uno One-to-One. Sabemos que User has_many Photo, por lo cual:

1
class User extends Eloquent {
2
    public function photos()
3
    {
4
        return $this->has_many('Photo');
5
    }
6
}
7
...
8
...
9
...
10
class Photo extends Eloquent {
11
    public function user()
12
    {
13
        return $this->belongs_to('User');
14
    }
15
}

La principal diferencia aquí con has_one es que la función que usaremos para recuperar las fotos de un usuario ahora devolverá una matriz de objetos del modelo Photo. Por lo tanto, si quisiéramos traer todas las fotos de un usuario, podríamos hacer lo siguiente:

1
$photos = User::find($user_id)->photos;
2
foreach($photos as $photo) {
3
    ...
4
    ...
5
    ...
6
}

No, referirse a photos como una propiedad no es un error tipográfico. Laravel nos da ese sabor dulce. También podríamos hacer:

1
$photos = User::find($user_id)->photos()->get();

Relaciones de muchos a muchos - Mant-to-Many

Este es un poco complicado, pero una vez implementado, hace que sea fácil manejar las relaciones de muchos a muchos entre los modelos. Imaginemos, por ejemplo, que, de nuevo, tienes un modelo User y cada uno de estos usuarios puede tener varios grupos y para eso usamos el modelo Group. Un grupo también puede tener varios usuarios. Usaremos tres tablas para representar estas relaciones particulares:

  • Users - tabla donde están todos nuestros usuarios
  • Groups - tabla donde están todos nuestros grupos
  • Group User - tabla que enumera todos los usuarios de un grupo

La convención de estructura de tabla que Eloquent buscará será algo como esto:

  • users
    • id
    • ... otras columnas
  • groups
    • id
    • ... otras columnas
  • group_user
    • id
    • user_id
    • group_id
    • ... otras columnas

Otra convención a tener en cuenta aquí es que la tabla intermedia, group_user, son los nombres singulares de las dos tablas que estás conectando, organizados alfabéticamente con un carácter de subrayado. Como siempre, somos libres de anular esto.

Así es como se verá el código dentro de cada uno de los modelos para estas tres tablas:

1
class User extends Eloquent {
2
    public function groups()
3
    {
4
        //if we wanted to override the default naming convention

5
        //for the intermediate table, we can do it like so:

6
        //return $this->has_many_and_belongs_to('Group', 'group_listings');

7
        
8
        return $this->has_many_and_belongs_to('Group');
9
    }
10
}
11
...
12
...
13
...
14
class Group extends Eloquent {
15
    public function users()
16
    {
17
        //if we wanted to override the default naming convention

18
        //for the intermediate table, we can do it like so:

19
        //return $this->has_many_and_belongs_to('User', 'group_listings');

20
        
21
        return $this->has_many_and_belongs_to('User');
22
    }
23
}
24
...
25
...
26
...
27
class Group_User extends Eloquent {
28
    public function group()
29
    {
30
        return $this->has_one('Group');
31
    }
32
    
33
    public function user()
34
    {
35
        return $this->has_one('User');
36
    }
37
}

Con esto en su lugar, podemos aprovechar las funciones de relación de Eloquent:

1
//Get a user's groups

2
$groups = User::find($user_id)->groups;
3
4
//Get all users in a group

5
$users = Group::find($group_id)->users;

Paso 1 - Creación de la base de datos Instapics

Instapics

Continuando con nuestra aplicación web, Instapics, comencemos creando la base de datos de nuestra aplicación. Para ello, vamos a anotar las funcionalidades deseadas de la aplicación:

  • Los usuarios pueden iniciar sesión y registrarse para obtener una cuenta
  • Los usuarios pueden seguir a otros usuarios para ver las fotos que han subido
  • Los usuarios pueden subir su propia foto y aplicar un filtro a ella
  • Los usuarios pueden comentar y darle me gusta a otras fotos

Para esto, podemos deducir las tablas de base de datos que necesitaremos:

  • users

    • id (uno a uno con user_profiles.user_id, muchos a muchos usando la misma tabla relationships.follower_id y followed_id, uno a muchos con photos.user_id y photo_comments.user_id)
    • email
    • password
    • created_at
    • updated_at
  • user_profiles

    • id
    • user_id (uno a uno con users.id)
    • name
    • profile_photo
  • relationships

    • id
    • follower_id (uno a uno con users.id)
    • followed_id (uno a uno con users.id)
    • created_at
    • updated_at
  • photos

    • id (uno a muchos con photo_comments.user_id)
    • user_id (uno a uno con users.id)
    • location
    • description
    • created_at
    • updated_at
  • photo_comments

    • id
    • user_id (uno a uno con users.id)
    • photo_id (uno a uno con photos.id)
    • message
    • created_at
    • updated_at

Vamos a continuar y vamos crear estas tablas. Para este proyecto, usaré MySQL; no dudes en copiar y pegar estos comandos.

1
CREATE DATABASE `instapics`;
2
USE `instapics`;
3
4
CREATE TABLE `instapics`.`users` (
5
  `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
6
  `email` VARCHAR(100) NOT NULL,
7
  `password` VARCHAR(100) NOT NULL,
8
  `created_at` DATETIME NOT NULL,
9
  `updated_at` DATETIME NOT NULL,
10
  PRIMARY KEY (`id`),
11
  UNIQUE INDEX `Index_email`(`email`)
12
)
13
ENGINE = InnoDB
14
CHARACTER SET utf8 COLLATE utf8_general_ci;
15
16
CREATE TABLE `instapics`.`user_profiles` (
17
  `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
18
  `user_id` INTEGER UNSIGNED NOT NULL,
19
  `name` TEXT NOT NULL,
20
  `profile_photo` TEXT NOT NULL,
21
  PRIMARY KEY (`id`),
22
  UNIQUE INDEX `Index_user_id`(`user_id`),
23
  CONSTRAINT `FK_user_profiles_user_id` FOREIGN KEY `FK_user_profiles_user_id` (`user_id`)
24
    REFERENCES `users` (`id`)
25
    ON DELETE CASCADE
26
    ON UPDATE CASCADE
27
)
28
ENGINE = InnoDB
29
CHARACTER SET utf8 COLLATE utf8_general_ci;
30
31
CREATE TABLE `instapics`.`relationships` (
32
  `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
33
  `follower_id` INTEGER UNSIGNED NOT NULL,
34
  `followed_id` INTEGER UNSIGNED NOT NULL,
35
  `created_at` DATETIME NOT NULL,
36
  `updated_at` DATETIME NOT NULL,
37
  PRIMARY KEY (`id`),
38
  UNIQUE INDEX `Index_follower_id_followed_id`(`follower_id`, `followed_id`),
39
  CONSTRAINT `FK_relationships_follower_id` FOREIGN KEY `FK_relationships_follower_id` (`follower_id`)
40
    REFERENCES `users` (`id`)
41
    ON DELETE CASCADE
42
    ON UPDATE CASCADE,
43
  CONSTRAINT `FK_relationships_followed_id` FOREIGN KEY `FK_relationships_followed_id` (`followed_id`)
44
    REFERENCES `users` (`id`)
45
    ON DELETE CASCADE
46
    ON UPDATE CASCADE
47
)
48
ENGINE = InnoDB
49
CHARACTER SET utf8 COLLATE utf8_general_ci;
50
51
CREATE TABLE `instapics`.`photos` (
52
  `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
53
  `user_id` INTEGER UNSIGNED NOT NULL,
54
  `location` TEXT NOT NULL,
55
  `description` TEXT NOT NULL,
56
  `created_at` DATETIME NOT NULL,
57
  `updated_at` DATETIME NOT NULL,
58
  PRIMARY KEY (`id`),
59
  CONSTRAINT `FK_photos_user_id` FOREIGN KEY `FK_photos_user_id` (`user_id`)
60
    REFERENCES `users` (`id`)
61
    ON DELETE CASCADE
62
    ON UPDATE CASCADE
63
)
64
ENGINE = InnoDB
65
CHARACTER SET utf8 COLLATE utf8_general_ci;
66
67
CREATE TABLE `instapics`.`photo_comments` (
68
  `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
69
  `user_id` INTEGER UNSIGNED NOT NULL,
70
  `photo_id` INTEGER UNSIGNED NOT NULL,
71
  `message` TEXT NOT NULL,
72
  `created_at` DATETIME NOT NULL,
73
  `updated_at` DATETIME NOT NULL,
74
  PRIMARY KEY (`id`),
75
  CONSTRAINT `FK_photo_comments_user_id` FOREIGN KEY `FK_photo_comments_user_id` (`user_id`)
76
    REFERENCES `users` (`id`)
77
    ON DELETE CASCADE
78
    ON UPDATE CASCADE,
79
  CONSTRAINT `FK_photo_comments_photo_id` FOREIGN KEY `FK_photo_comments_photo_id` (`photo_id`)
80
    REFERENCES `photos` (`id`)
81
    ON DELETE CASCADE
82
    ON UPDATE CASCADE
83
)
84
ENGINE = InnoDB
85
CHARACTER SET utf8 COLLATE utf8_general_ci;

Alternativamente, podrías usar las migraciones, pero las revisaremos en una lección futura.


Paso 2 - Configurar la base de datos de Laravel

Antes de hacer nada con los modelos Laravel, necesitamos configurar la base de datos de nuestra instalación de Laravel. Abre application/config/database.php, para encontrar algunos de estos ajustes:

  • profile - establecer esto en true registrará todas las horas de las consultas en SQL en los registros de Laravel. Deja esto como true por ahora.
  • fetch - el tipo de datos devueltos de PDO. El valor predeterminado es PDO::FETCH_CLASS y debe dejarse así.
  • default - este es el nombre de la configuración de conexión utilizada por la aplicación. El nombre hace referencia al índice de la matriz $connections justo debajo
  • connections: una matriz asociativa de las posibles conexiones para la aplicación.

    • driver: el tipo de servidor de base de datos. Puede ser pgsql, sqlite, mysql o sqlsrv
    • host - el nombre de host del servidor de tu base de datos
    • database - el nombre de la base de datos
    • username - nombre de usuario para usar en el servidor de la base de datos
    • password - contraseña para usar en el servidor de la base de datos
    • charset - El tipo de charset para usar en el servidor de la base de datos
    • prefix - prefijo de tabla en la base de datos, si hay
  • redis: si planeas utilizar la biblioteca Redis de Laravel, puedes configurar la información del servidor aquí.

Para los fines de este tutorial, usaremos MySQL. Tu archivo database.php debería tener un aspecto similar al siguiente (eliminé los comentarios, pero deberías dejarlos):

1
return array(
2
	'profile' => true,
3
	'fetch' => PDO::FETCH_CLASS,
4
	'default' => 'mysql',
5
	'connections' => array(
6
		'mysql' => array(
7
			'driver'   => 'mysql',
8
			'host'     => 'localhost',
9
			'database' => 'instapics',
10
			'username' => 'root',
11
			'password' => '(yourpassword)',
12
			'charset'  => 'utf8',
13
			'prefix'   => '',
14
		),
15
	),
16
	'redis' => array(
17
		'default' => array(
18
			'host'     => '127.0.0.1',
19
			'port'     => 6379,
20
			'database' => 0
21
		),
22
	)
23
);

Paso 3 - Creación de tu primer modelo en laravel

Comienza creando un modelo de Laravel dentro de la carpeta application/models. Crea user.php dentro y añade el siguiente código:

1
class User extends Eloquent {
2
3
}

Ahora, sobre la base de nuestra revisión de cuáles son las relaciones de User, necesitamos codificar los métodos de las relaciones para todas ellas:

1
class User extends Eloquent {
2
    
3
    //setting $timestamp to true so Eloquent

4
    //will automatically set the created_at

5
    //and updated_at values

6
    public static $timestamps = true;
7
    
8
    public function user_profile()
9
    {
10
        return $this->has_one('User_Profile');
11
    }
12
    
13
    public function followers()
14
    {
15
        return $this->has_many_and_belongs_to('User', 'relationships', 'followed_id', 'follower_id');
16
    }
17
    
18
    public function following()
19
    {
20
        return $this->has_many_and_belongs_to('User', 'relationships', 'follower_id', 'followed_id');
21
    }
22
    
23
    public function photos()
24
    {
25
        return $this->has_many('Photo');
26
    }
27
    
28
    public function photo_comment()
29
    {
30
        return $this->has_many('Photo_Comment');
31
    }
32
}

Notablemente, hacemos uso de algunas funciones avanzadas de muchos a muchos aquí, debido a la estructura de la tabla de nuestro modelo 'follower' (es decir, la tabla users hace referencia a la tabla relationships, la cual hace referencia a la tabla users de nuevo). La función has_many_and_belongs_to tiene la siguiente firma de método:

1
/**

2
 * Get the query for a many-to-many relationship.

3
 *

4
 * @param  string        $model

5
 * @param  string        $table

6
 * @param  string        $foreign

7
 * @param  string        $other

8
 * @return Relationship

9
*/
10
public function has_many_and_belongs_to($model, $table = null, $foreign = null, $other = null)

Esto realmente nos permite crear un modelo que tiene una relación de muchos a muchos con sí mismo (es decir, los usuarios siguen a otros usuarios). Utilizamos followers y following como los nombres de los métodos en el modelo User para permitirnos obtener seguidores de un usuario u obtener todos los usuarios que un solo usuario está siguiendo, respectivamente.

Siguiendo el ejemplo del modelo User, crea los otros modelos. Cuando termines, debes tener:

  • application/models/photo.php
  • application/models/photo_comment.php
  • application/models/relationship.php
  • application/models/user.php
  • application/models/user_profile.php

Estos archivos estarán en el repositorio Git del tutorial, por lo que si prefieres descargarlos, puedes encontrarlos aquí: https://github.com/nikkobautista/laravel-tutorial


Paso 4 - Crear las funciones del usuario para Instapics

Comencemos a usar nuestros modelos creando algunas de las funciones de usuario que necesitaremos en la aplicación. En primer lugar: registro de usuarios. Desde el tutorial anterior, ya hemos creado un formulario de registro/inicio de sesión en la página de inicio. En este momento, esto no está haciendo nada, pero vamos a conectarlo a un controlador de User, para que se pueda autenticar mediante la acción authenticate. Crea un archivo en application/controllers/user.php con el siguiente código:

1
class User_Controller extends Base_Controller
2
{    
3
    public function action_authenticate()
4
    {
5
        
6
    }
7
}

Abre application/views/home/index.blade.php y busca el formulario de inicio de sesión. Actualiza el formulario de la línea 18 para enviarlo al método action_authenticate():

1
<form class="well" method="POST" action="user/authenticate">

Volviendo al controlador User_Controller, agreguemos un poco de código en action_authenticate():

1
class User_Controller extends Base_Controller
2
{    
3
    public function action_authenticate()
4
    {
5
        $email = Input::get('email');
6
        $password = Input::get('password');
7
        $new_user = Input::get('new_user', 'off');
8
        
9
        if( $new_user == 'on' ) {
10
            try {
11
                $user = new User();
12
                $user->email = $email;
13
                $user->password = Hash::make($password);
14
                $user->save();
15
                Auth::login($user);
16
            
17
                return Redirect::to('dashboard/index');
18
            }  catch( Exception $e ) {
19
                echo "Faield to create new user!";
20
            }
21
        } else {
22
            $credentials = array(
23
                'username' => $email,
24
                'password' => $password
25
            );
26
            if( Auth::attempt($credentials)) {
27
                return Redirect::to('dashboard/index');
28
            } else {
29
                echo "Failed to login!";
30
            }
31
        }
32
    }
33
}

Vamos a desglosar lo que hemos hecho aquí hasta ahora:

  • Usamos la librería Input para obtener los datos del formulario enviado
  • Si se ha marcado el indicador $new_user, creamos un nuevo usuario, utilizando la biblioteca Hash para generar una contraseña cifrada.
  • Inicia sesión en el nuevo usuario con la librería Auth
  • Si el indicador $new_user estaba desmarcado, creamos una matriz $credentials y la usamos con la librería Auth.
  • Si Auth::attempt es verdadero, significa que las credenciales eran correctas y hemos iniciado sesión
  • De lo contrario, significa que las credenciales estaban equivocadas.
  • En ambos escenarios, redirigimos al controlador Dashboard, a la acción index cuando se realice correctamente. Y mostraremos un mensaje de error en caso contrario.

La librería Input

La función básica de la librería Input es habilitar la obtención de los datos del formulario. Por ejemplo, en el controlador del usuario, usamos Input::get('email'); para obtener el valor del correo electrónico del formulario. Es importante tener en cuenta que el método get se utiliza para todos los tipos de solicitudes y no solo para la matriz $_GET.

Puedes leer más sobre la librería Input aquí: http://laravel.com/docs/input#input

La librería Auth

Laravel viene con su propio mecanismo de autenticación, la biblioteca Auth. Puede hacer las siguientes características con respecto a la autenticación de usuario.

Crea una contraseña encriptada

Podemos hacer uso de la librería Hash de la siguiente manera:

1
$password = Hash::make($plaintext_password);

Este método crea una contraseña encriptada y segura para un usuario, utilizando la clave de cifrado que establecemos en el archivo de configuración. Para comprobar si un hash es correcto, puedes utilizar:

1
if( Hash::check($plaintext_password, $hashed_password) == true ) {
2
    echo 'Password is correct.';
3
}

Iniciar sesión en un usuario

Para ello, usamos el método attempt de la librería Auth. Antes de eso, sin embargo, construimos una matriz $credentials, que es una matriz asociativa con los índices username y password:

1
$credentials = array(
2
    'username' => 'yourname@youremail.com',
3
    'password' => 'yourpassword'
4
);
5
if( Auth::attempt($credentials) == true ) {
6
    echo 'User is logged in';
7
} else {
8
    echo 'Credentials failed';
9
}

Es importante tener en cuenta que una vez que un intento es "exitoso", el usuario inicia sesión automáticamente.

Hacer que un usuario inicie/cierre sesión

A veces, tendremos que iniciar sesión en un usuario sin usar el método attempt (por ejemplo, al iniciar sesión en un usuario desde un enlace dentro de un correo electrónico o después del registro). Podemos hacerlo con el método Auth::login:

1
Auth::login($user); //where $user is a User object

2
Auth::login(42); //where 42 is the User's ID

Por otro lado, también tenemos un método Auth::logout para cerrar la sesión de los usuarios:

1
Auth::logout();

Esto terminará la sesión del usuario.

Recuperar los datos del usuario que ha iniciado sesión

El método Auth::user nos permite recuperar el objeto de usuario que ha iniciado sesión, así como cualquier información adjunta a él:

1
$email = Auth::user()->email;
2
$created_at = Auth::user()->created_at;

Configuración de la librería Auth

La librería Auth debe configurarse antes de usarla (aunque los valores predeterminados funcionarán con la mayoría de los proyectos, como este). Las variables de configuración son:

  • driver - esto puede ser Eloquent o Fluent. Los desarrolladores pueden escribir sus propios controladores extendiendo la clase Driver en laravel/auth/drivers.
  • username: este es el nombre de la columna de lo que representa el "nombre de usuario" de tu usuario en la tabla de la base de datos.
  • model - cuando se utiliza Eloquent, esta es la clase de modelo que utiliza la librería Auth
  • table - cuando se utiliza el controlador de autenticación Fluent, se determina la tabla de base de datos para los usuarios de la aplicación

Nuestro proyecto, Instapics, utiliza los valores predeterminados en el archivo de configuración auth.php, por lo que no necesitamos cambiar nada en él.

Volviendo al proyecto, ¡prueba las características de inicio de sesión/registro de Instapics! Bastante ingenioso, ¿no? Sin embargo, notarás que aún no tenemos nada en el controlador Dashboard, así que vamos a trabajar en él a continuación.


Paso 5 - Crear el panel de Instapics

Lo primero que tenemos que hacer es crear el controlador Dashboard, con la acción index. Crea el archivo application/controllers/dashboard.php y coloca el siguiente código:

1
class Dashboard_Controller extends Base_Controller
2
{
3
    public function action_index()
4
    {
5
        $photos = Auth::user()->photos()->order_by('created_at', 'desc')->order_by('id', 'desc')->get();
6
        return View::make('dashboard.index', array('photos' => $photos));
7
    }
8
}

Ahora necesitamos crear la página index.blade.php del panel. Crea application/views/dashboard/index.blade.php y añade lo siguiente:

1
@layout('layouts/main')
2
3
@section('navigation')
4
@parent
5
<li><a href="user/logout">Logout</a></li>
6
@endsection
7
8
@section('content')
9
<div class="row">
10
    <div class="span3">
11
        <div class="well sidebar-nav">
12
            <ul class="nav nav-list">
13
                <li class="nav-header">Followers</li>
14
            </ul>
15
            <div style="margin-left: 10px">
16
                @forelse (Auth::user()->followers as $follower)
17
                    <div style="float: left; width: 30px; margin: 0px 3px 3px 5px;">
18
                        <img src="http://nettuts.s3.amazonaws.com/2069_laravel_2/http://gravatar.com/avatar/{{ md5(strtolower(trim($follower->email))) }}?s=25&d=retro" alt="Follower" title="{{ $follower->email }}" />
19
                    </div>
20
                @empty
21
                    <div>You have no followers.</div>
22
                @endforelse
23
                <div style="clear: both"></div>
24
            </div>
25
            
26
            <ul class="nav nav-list">
27
                <li class="nav-header">Following</li>
28
            </ul>
29
            <div style="margin-left: 10px">
30
                @forelse (Auth::user()->following as $following)
31
                    <div style="float: left; width: 30px; margin: 0px 3px 3px 5px;">
32
                        <img src="http://nettuts.s3.amazonaws.com/2069_laravel_2/http://gravatar.com/avatar/{{ md5(strtolower(trim($following->email))) }}?s=25&d=retro" alt="Following" title="{{ $following->email }}" />
33
                    </div>
34
                @empty
35
                    <div>You are not following anybody.</div>
36
                @endforelse
37
                <div style="clear: both"></div>
38
            </div>
39
        </div>
40
    </div>
41
    <div class="span9">
42
        <h1>Your Photos</h1>
43
        @forelse ($photos as $photo)
44
        <div class="well" style="text-align: center">
45
            <img src="http://nettuts.s3.amazonaws.com/2069_laravel_2/{{ $photo->location }}" alt="{{ $photo->description }}" title="{{ $photo->description }}" />
46
            <p>{{ $photo->description }}</p>
47
        </div>
48
        @empty
49
        <div class="alert alert-info">
50
            <h4 class="alert-heading">Awww!</h4>
51
            <p>Seems like you don't have any photos yet. <a href="#">Upload a new one?</a></p>
52
        </div>
53
        @endforelse
54
    </div>
55
</div>
56
@endsection

Actualiza la página del panel, deberías ver esto:

Instapics DashboardInstapics DashboardInstapics Dashboard

¿Luce un poco vacío? Agrega esto al controlador Dashboard y ejecútalo accediendo a dashboard/insert_test_data en tu navegador:

1
public function action_insert_test_data()
2
{
3
    $logged_in_user = Auth::user();
4
    
5
    for( $x = 0; $x < 10; $x++ ) {
6
        $email = rand().'@gmail.com';
7
        $user = new User();
8
        $user->email = $email;
9
        $user->password = Hash::make($email);
10
        $user->save();
11
        
12
        $logged_in_user->followers()->attach($user->id);
13
        if( $x > 5 ) {
14
            $logged_in_user->following()->attach($user->id);
15
        }
16
    }
17
    
18
    $photos = array(
19
        array(
20
            'user_id' => $logged_in_user->id,
21
            'location' => 'http://farm6.staticflickr.com/5044/5319042359_68fb1f91b4.jpg',
22
            'description' => 'Dusty Memories, The Girl in the Black Beret (http://www.flickr.com/photos/cloudy-day/)'
23
        ),
24
        array(
25
            'user_id' => $logged_in_user->id,
26
            'location' => 'http://farm3.staticflickr.com/2354/2180198946_a7889e3d5c.jpg',
27
            'description' => 'Rascals, Tannenberg (http://www.flickr.com/photos/tannenberg/)'
28
        ),
29
        array(
30
            'user_id' => $logged_in_user->id,
31
            'location' => 'http://farm7.staticflickr.com/6139/5922361568_85628771cd.jpg',
32
            'description' => 'Sunset, Funset, Nikko Bautista (http://www.flickr.com/photos/nikkobautista/)'
33
        )
34
    );
35
    $logged_in_user->photos()->save($photos);
36
}

Cuando actualices la página, verás cómo se ve con los datos de ejemplo insertados:

Instapics Dashboard w Sample DataInstapics Dashboard w Sample DataInstapics Dashboard w Sample Data

Conclusión

En la segunda parte de nuestra serie Laravel, aprendimos:

  • Algunos antecedentes sobre lo que son los "Modelos"
  • Qué es el Eloquent ORM
  • Cómo configurar la base de datos de Laravel
  • Cómo crear tu primer Modelo en Laravel
  • Las funciones básicas de las librerías Auth y Input
  • Hacer uso de Eloquent ORM en una vista

Eloquent realmente es una implementación ORM impresionante - es rápido y tiene un montón de características que hacen que las interacciones con la base de datos en cualquier aplicación sean tan simple como sea posible.

A continuación, en nuestra serie Aplicaciones web desde cero con Laravel, aprenderemos más sobre el uso de los filtros de Laravel, la librería Validation de Laravel, ¡y cómo trabajar con archivos en Laravel!

¿Qué opinas de Eloquent ORM de Laravel? ¿Es algo que te parece útil? ¡Avísame en los comentarios! Y, si eres miembro de Tuts+ Premium, ¡mantente atento a nuestro próximo curso de Laravel Essentials!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.