Laravel, parte 11: Modelos y relaciones

Dijimos en su momento que en Laravel los modelos son la representación de las tablas de la base de datos, son los encargados de comunicarse con la base de datos, como una suerte de intermediario entre ésta y el resto de la aplicación. Por tanto los modelos, al igual que las tablas también estará relacionados entre sí.

Supongo que la mayoría de la gente que llegue a leer esta publicación tendrá conocimientos, aunque sean básicos, de  base de datos SQL, entonces seguro estará familiarizado con las relaciones entre tablas. Vamos a repasarlas.

Las relaciones son:

1 a 1, se dan cuando un registro tiene relación con otro y sólo con ése, y a su vez éste también sólo tendrá relación con el primero. Por ejemplo una persona y su documento, podemos decir que esta persona “tiene un” documento y este documento “le pertenece” a esta persona. De 1 a 1, la persona tendrá sólo un documento, y el documento le pertenece a esa persona solamente.

1 a N (uno a muchos) En este caso un registro estará relacionado, o mejor dichos “tendrá muchos” registros, pero estos sólo “le pertenecerán” a ese primer registro. Por ejemplo un usuario podrá tener muchas publicaciones, pero cada publicación tendrá como autor a un sólo usuario.

N a N (muchos a muchos) Aquí cada registro podrá estar relacionado con varios registros, que a su vez estos también tendrán relación con otros. Por ejemplo a una persona le puede gustar distintas bandas de música, pero éstas bandas a su vez pueden gustarles a varias personas. En el caso de las relaciones de N a N, siempre se genera una tabla intermedia para guardar en cada registro las relaciones entre ambos.

Bien, continuemos con nuestra pequeña aplicación. Hasta ahora nosotros tenemos una tabla users con su respectivo modelo User, para trabajar con los registros de los distintos usuarios de nuestra base de datos. Entonces vamos a crear una nueva tabla, y obviamente modelo, para ir guardando las publicaciones que van haciendo estos usuarios. Tendremos una tabla posts y un modelo Post, La relación entre los usuarios (User) y las publicaciones (Post) será la siguiente: un usuario podrá crear varias publicaciones, y cada publicación le va a pertenecer a un usuario solo, por tanto la relación será de uno a muchos.

Por empezar vamos a crear una nueva migración, la nueva tabla posts. Así que vamos abrir nuestra consola, vamos a entrar nuestro proyecto con cd:

cd C:\xampp\htdocs\mi_proyecto_laravel

Y una vez dentro vamos a escribir lo siguiente:

php artisan migrate:make create_posts_table

Debería haberse generado nuestra migración así que vamos a app -> database -> migrations -> xxxxxxxxxxxx_create_posts_table (las x representan el número que se haya generado) y vamos a editar este archivo con el siguiente código:

El método up() quedará de la siguiente forma:

public function up()
{
   Schema::table('posts', function($table) {
      $table->create();
      $table->increments('id');
      $table->string('title');
      $table->string('body');
      $table->integer('user_id');
      $table->timestamps();
   });
}

Y el método down():

public function down()
{
   Schema::drop('posts');
}

Si seguiste una de las anteriores publicaciones que hice, Laravel, parte 4: Migraciones, deberías entender el código perfectamente. Vamos a crear una tabla posts (recomendable en plural) con su id y tres campos: title y body, para el título y el contenido de la publicación respectivamente, y un campo numérico para guardar el id del usuario, llamado user_id. A su vez tendremos un registro de fecha y hora de cuándo los registros fueron creados y/o modificados.

Así que sin más palabrería vamos a pasar a la acción, y vamos a terminar de crear nuestra tabla, volviendo la consola y escribiendo:

php artisan migrate

Bien, ya tenemos nuestra tabla, ahora sólo nos falta el modelo que se comunicará con la misma.

Vamos dentro de app -> models y dentro crearemos un nuevo modelo llamado: Post.php:

<?php
class Post extends Eloquent {
   public function user(){
      return $this->belongsTo('User');
   }
}
?>

El modelo obviamente heredará de la clase Eloquent, para contar con todas las funcionalidades que hemos visto que pueden tener los modelos en Laravel. También tendrá un método user(), aquí vamos a indicar que el Post le pertenece a User:

public function user(){
   return $this->belongsTo('User');
}

Ahora tendremos que ir al otro extremo de la unión e indicar que User tendrá muchos Post. Así que vamos a app -> modelos -> User.php y vamos a editar nuestro modelo User, con el que venimos trabajando desde hace muchas publicaciones, agregando el siguiente método a la clase:

public function posts(){
   return $this->hasMany('Post');
}

Bien, con esto es suficiente para que Laravel entienda que User tendrá muchos Post (hasMany), mientras que Post le va a pertenece a un User (belongsTo)

Ahora podemos crear una nueva acción de testeo e insertar algunos registros para Post:

Route::get('test', function(){
   //Registro 1
   $post1 = new Post();
   $post1->title = 'Título 1';
   $post1->body = 'Contenido 1';
   $post1->user_id = 1;
   $post1->save();
   //Registro 1
   $post2 = new Post();
   $post2->title = 'Título 2';
   $post2->body = 'Contenido 2';
   $post2->user_id = 1;
   $post2->save();
   //Registro 1
   $post3 = new Post();
   $post3->title = 'Título 3';
   $post3->body = 'Contenido 3';
   $post3->user_id = 1;
   $post3->save();
});

Podemos ejecutarlo y así guardar tres registros en la base de datos. En mi caso usé el usuario con el id 1, ya que en mi base tengo un usuario con ese número de id.

Una vez insertados estos registros podemos recuperarlos, pero desde el modelo User:

Route::get('test', function(){
   $user = User::find(1);
   $posts = $user->posts;
   $lista = '<ul>';
   foreach($posts as $item){
      $lista .= '<li>';
      $lista .= '<h2> ' . $item['title'] . ' </h2>';
      $lista .= '<div> ' . $item['body'] . ' </div>';
      $lista .= '</li>';
   }
   $lista .= '</ul>';
   return $lista;
});

Para ver más sobre relaciones entre modelos podés consultar la documentación desde la página de Laravel:

https://laravel.com/docs/eloquent#relationships

Saludos!

Anterior: Laravel, parte 10: Login

Siguiente: Laravel, parte 12: Javascript, Css e imágenes

Redes sociables

    4 Replies to “Laravel, parte 11: Modelos y relaciones”

    1. Gracias me ha servido de gran ayuda , tengo una pregunta como puedo comprovar si las relaciones se hisieron correctamente , porque he segido todo el tutorial y cambie $post3->user_id = 1; por $post3->user_id = 8 un usuario que no esta en la base de datos y no me genera error , lo cual di con la conclución que no estan relacionas , muchas gracias por su respuesta.

      1. En realidad esa relación es lógica, y no existe como tal en la base de datos, a menos que vos crees los foreign key manualmente.

        Sucede que Laravel está preparado para trabajar con distintas bases de datos, y en algunos casos como sqlite, no existe el concepto de clave externa.

        Saludos!

    2. Muchas gracias lo entidí, solo tengo una pregunta, es necesario crear la llaves foraneas manualmente? para realizar una pagína web con laravel.
      Gracias por todo me a servido de gran ayuda los tutoriales.

      1. No, si la base de datos sólo va a ser controlada por tu aplicación, entonces dejalo así.

        Saludos!

    Comments are closed.