En Laravel los modelos se controlan por un ORM llamado Eloquent, al menos los modelos que están implementados como datos en una base de datos, pero no es un requisito, de modo que podríamos trabajar con otros ORM o incluso bajar a un nivel más bajo y trabajar con Query Builder o PDO directamente, o con las extensiones de nuestra base de datos en particular, lo que no sería muy recomendable en realidad.
En Laravel por convención :
por cada tabla de la base de datos se crea un modelo
Ejemplo tabla profesores - modelo Profesor
class Profesor extends Model
cada fila de una tabla corresponde a un objeto,
Una fila de la tabla profesores
$profesor= new Profesor
el objeto tiene propiedades que corresponde a los atributos de la tabla de una determinada fila, como se muestra en la figura.
El campo nombre_apellido propiedad clase Profesor
$profesor= $profesor→nombre_apellido
En el caso de ser un modelo Eloquent, los modelos están directamente asociados a una entidad y a su vez a una tabla de la base de datos, por lo que un modelo que se llama User está directamente relacionado con una tabla llamada con el mismo nombre en la base de datos, pero en minúscula y acabado en plural, ej "users".
Laravel Eloquent Model.
Laravel ofrece un ORM muy potente (acrónimo de mapeo relacional de objetos).
Se trata sencillamente que todos los elementos de la base de datos tienen una representación en forma de objetos manipulables.
Con Eloquent, una tabla se representa mediante una clase que amplía la clase Model .
El archivo se puede encontrar en la carpeta app/Models:
Con este contenido
Los modelos tienen la primera letra en mayúscula, por implementarse mediante clases. Los archivos donde guardamos el código de los modelos también deben tener esa primera letra en mayúscula.
Este modelo usará el motor del ORM de Eloquent y lo puedes ver porque está haciendo uso de la clase Model que está en el namespace Illuminate\Database\Eloquent. Esa clase se le asigna un alias llamado "Model" (el mismo nombre de la clase que luego hacemos el extends) gracias a la sentencia:
El modelo se crea dentro del namespace "App", definido por la primera línea de código:
Acceder a datos del modelo
Desde los controladores querremos acceder a datos que mantienen los modelos: consultas, modificaciones, etc. Esas operaciones se hacen a través de la clase del modelo que acabamos de implementar.
De momento veamos cómo implementar una selección de todos los datos que tenemos en el modelo, invocando el método all() sobre el modelo que acabamos de crear.
Este código estaría en un controlador, o en otra clase desde la que queramos acceder a los datos del modelo. Como puedes ver, para referirnos al modelo debemos indicar el
donde lo podemos encontrar, que en nuestro caso era "App".
Esa línea de código, nos devuelve una colección con los datos encontrados. Aunque de momento todavía no nos va a funcionar, porque la tabla "tests" no está creada en nuestro sistema gestor. En cambio obtendremos un error como este:
Una vez creada la tabla en la base de datos y metiendo datos en estas, podemos ver para mostrar la salida por la página y así poder leerla debes hacer un print_r() o var_dump() porque es una colección. También puedes usar la función dd() que te ofrece Laravel.
Pero para hablar de modelos debemos entender como gestionar las BBDD.
Para hacerlo Laravel nos brinda:
Migraciones
Puede crear un modelo al mismo tiempo que la migración de la tabla con esta sintaxis:
Seeders
Model Factories
Podemos crear el modelo, migración, seeder y controlador , todos a la vez o seleccionando lo que queramos
-m añade la migración
-s añade el seeder
-cr añade el controlador (c) tipo resource (r)
También podemos crear el modelo a la vez que el controlador:
Los modelos usan convenciones para que a Laravel se le facilite el trabajo y nos ahorre tanto líneas de código como tiempo para relacionar más modelos, las cuales son:
El nombre de los modelos se escribe en singular, en contraste con las tablas de la BD que se escriben en plural.
Usan notación UpperCamelCase para sus nombres.
Estas convenciones nos ayudan a detectar automáticamente las tablas, por ejemplo: el modelo User se encuentra en singular y con notación UpperCamelCase y para Laravel poder definir que tabla es la que esta ligada a este modelo le es suficiente con realizar la conversión a notación underscore y plural, dando como resultado la tabla: users.
Y esto aplica para cuando queremos crear nuestros modelos, si tenemos una tabla en la base de datos con la que queremos trabajar que se llama user_profiles, vemos que se encuentra con las convenciones para tablas de bases de datos (plural y underscore), entonces el modelo para esta tabla cambiando las convenciones seria: UserProfile (singular y UpperCamelCase).
Protected
Si por ejemplo tenemos el modelo Pastel,
Modificar el nombre de la tabla
Si queremos cambiar la convención con el nombre de la tabla , tendremos que poner la línea:
con esto nuestra tabla será pasteles, no pastel.
Modificar la clave primaria
Las claves primarias en Laravel también tienen su convención. Básicamente toda tabla tiene una columna llamada "id" que será "autoincrement" y que hará las veces de clave primaria. De nuevo, si esto no se ajusta a nuestra realidad solo tenemos que definir una propiedad llamada $primaryKey, asignando el nombre del campo que actúe como "Primary Key".
Indicamos la llave primaria de esta tabla.
fillable
Por defecto, todos los campos se tratan como protegidos y se debe indicar cuales pueden ser llenados de esta forma.
La propiedad fillable es para visualizar los campos de la tabla en las consultas sql,
Dentro de este array se pueden especificar cuáles de los campos de la tabla pueden ser llenados con asignación masiva (que es el caso cuando enviamos un formulario creando un array asociativo para ser guardado).
hidden
La propiedad hidden en cambio son para ocultar los campos de la tabla en las consultas sql.
Funciones
La función “ObtenerPasteles” utiliza el método all() para obtener todo el listado de los alumnos de la tabla.
La función “ObtenerPastelPorId” utiliza el método find() pasando un parámetro Id para obtener a un determinado pastel.
De manera predeterminada, Eloquent mantendrá las columnas created_at y updated_aten la tabla de su base de datos automáticamente. Simplemente agregue estas timestamp columnas a su tabla y Eloquent se encargará del resto. Si no desea que Eloquent mantenga estas columnas, agregue la siguiente propiedad a su modelo:
Deshabilitar marcas de tiempo automáticas
public $timestamps = false;
Relaciones Elocuent 1:1 (uno a uno)
La relación del modelo uno a uno es muy simple y básica, debe asegurarse de que una de las tablas tenga una clave que haga referencia a la identificación de la otra tabla.
Ejemplo:
Crearé una tabla de users y una tabla phones, ambas tablas están conectadas entre sí. ahora crearemos una relación uno a uno entre nosotros usando laravel Eloquent Model.
La relación uno a uno usará "hasOne()" y "belongsTo()" para la relación.
Crear Migraciones:
Creamos la migración de la tabla "users" y "phones". también agregaremos la clave externa con la tabla de users
Migración de la tabla de users:
Crear Tabla de Migración de phones con Clave Foránea
Crear modelo y agregar relación en ambos modelos
Seria un usuario tiene un teléfono y el teléfono pertenece a un usuario
Modelo User:
En el modelo de User, podemos crear la función phone () y agregar la relación del modelo de teléfono usando el método hasOne.
Modelo Phone:
Definimos una relación en el modelo Phone que nos permitirá acceder al usuario propietario del teléfono. Podemos definir el inverso de una relación hasOne usando el método belongsTo.
Si la clave externa en el modelo de Phone no es user_id, puede pasar un nombre de clave personalizado como segundo argumento para el método de belongsTo.
Recuperar Registros
Una vez que se define la relación, podemos recuperar el registro relacionado usando las propiedades dinámicas de Eloquent. Entonces, aquí podemos usar el modelo de usuario con función de teléfono.
Crear registros:
Relaciones Elocuent 1:N (uno a muchos)
La relación más común y simple entre dos tablas es la que hace coincidir un registro en una tabla con varios registros en la otra tabla, lo que se denomina relación de uno a muchos o relación 1:n .
Ejemplo:
En este ejemplo crearemos las tablas films y categories que están conectadas entre sí.
Tenemos la siguiente situación:
una categoría puede tener varias películas,
una película sólo pertenece a una categoría.
La relación uno a n usará "hasMany()" y "belongsTo()" para la relación.
Crear Migraciones:
La tabla categories
Crearemos una tabla para las categorías. Creamos nuestra migración al mismo tiempo que el modelo:
Migración de la tabla de categories:
La tabla films
Migración de la tabla de films:
Crear Modelos:
Aquí, crearemos un modelo de tabla de Film y Category. también usaremos "hasOne()" y "belongsTo()" para la relación de ambos modelos.
Modelo Category
Declaramos aquí con el método films (plural) que una categoría tiene varias ( hasMany ) films ( Film ). Tendremos así un método práctico para recuperar las películas de una categoría.
Modelo Film:
En el modelo Film codificaremos el recíproco:
Aquí tenemos el método de categoría (en singular) que te permite encontrar la categoría a la que pertenece la película (pertenece a ).
Recuperar Registros
Los dos métodos implementados facilitan la recuperación de un registro vinculado.
Por ejemplo para tener todas las películas de la categoría que tiene el id 1:
De la misma manera podemos encontrar la categoría de la película con id 1:
Ejemplo uso La vista show
Agregaremos en la vista el nombre de la categoría de la película.
En el controlador:
y en la vista:
Resumen
Una relación 1:n requiere la creación de una clave externa en el lado n .
Una relación en la base de datos requiere la implementación de métodos especiales en los modelos.
Hay varias maneras de manipular una relación.
Una composición de vistas hace posible compartir código para enviar información en vistas.
Relaciones Elocuent N:N (muchos a muchos)
La relación muchos a muchos es un poco más complicada que las relaciones uno a uno y uno a muchos.
Imagine una relación entre dos tablas A y B que permita decir:
Puedo tener una fila de la tabla A relacionada con varias filas de la tabla B,
Puedo tener una fila de la tabla B relacionada con varias filas de la tabla A.
Esta relación no se resuelve como en las relaciones 1:n ,con una clave foránea simple en una de las tablas. Efectivamente necesitaríamos claves en ambas tablas y varias claves, lo cual no es posible lograr.
La solución es crear una tabla intermedia (llamada tabla dinámica ) que se utiliza para almacenar claves externas. Por lo tanto, siempre tendremos nuestras tablas de películas y categorías , pero además una tabla dinámica entre las dos.
Migraciones
A nivel de migración, por categorías no va a cambiar. Para el de las películas, quitaremos la clave foránea, por lo que solo quedará esto:
Y también necesitamos la migración para la tabla dinámica que tendrá 2 claves foráneas: una para las categorías y otra para las películas:
Por convención, ponemos los dos nombres en singular y en orden alfabético, por lo que category_film .
Y codificamos la migración para las dos claves foráneas:
Esta vez ponemos en cascada para las claves foráneas. Entonces, si eliminamos una categoría o una película, la tabla dinámica se actualizará automáticamente.
Y refrescamos la base de datos:
A nivel de tabla, tenemos este esquema:
La relación entre las dos tablas está asegurada por la tabla dinámica. Esta tabla dinámica contiene las claves de las dos tablas:
category_id para almacenar la clave de la tabla de categorías,
film_id para almacenar la clave de la tabla de películas .
De esta forma podemos tener varios registros enlazados entre las dos tablas, basta cada vez con registrar las dos claves en la tabla dinámica. Obviamente, a nivel de código, requiere un poco de administración porque hay una tabla adicional para administrar.
Los modelos
En el modelo Categoría cambiamos la relación:
Declaramos aquí con el método películas (plural) que una categoría pertenece a varias ( belongsToMany ) películas ( Film ). Tendremos así un método práctico para recuperar las películas de una categoría.
Es exactamente lo mismo para el modelo de película :
Por cierto, eliminar la columna category_id en la propiedad $fillable .
Es el mismo principio que para las categorías ya que la relación es simétrica. Declaramos con el método de las categorías (plural) que una película pertenece a varias ( (belongsToMany ) categorías ( Category ).
La relación n:n
Aquí hay un diagrama de esta relación con los dos métodos simétricos:
Todos los métodos que hemos visto para la relación 1:n funcionan con la relación n:n , lo cual tiene sentido. El hecho de que haya una tabla dinámica no cambia el hecho de que la relación, vista desde una de las dos tablas, se parece mucho a una relación 1:n . Si elijo una categoría, por ejemplo, sé que puede tener varias películas relacionadas.
Seeder
Todavía tenemos que llenar las tablas para nuestras pruebas. No podemos quedarnos con lo que habíamos hecho porque ahora sería bueno que una película pertenezca a varias categorías. Así que aquí está el nuevo código de DatabaseSeeder :
Comenzamos creando 10 categorías. Luego creamos 40 películas y para cada una adjuntamos entre 1 y 4 categorías. Pasamos el identificador (podemos poner varios en una tabla como hice aquí) del registro relacionado al método de adjuntar y Eloquent se encarga de llenar la tabla dinámica. También existe el método de separación que hace exactamente lo contrario.
Viendo una película
Para la exhibición de una película, habíamos planeado especificar la categoría a la que pertenecía esa película. Es obvio que ahora tendremos que tener en cuenta el hecho de que podemos tener varias categorías. Actualizaremos el método show del controlador:
Sabemos que con la conexión de la ruta ya tenemos el modelo del Film Lo completamos añadiendo ( with ) sus categorías. A la salida tenemos una colección con la relación:
Esta forma de hacer las cosas se llama carga de ascensor (en contraposición a la carga diferida). Esto evita múltiples accesos a la base de datos para recuperar valores.
Ahora, en la vista Mostrar, ya no tenemos problemas para mostrar las categorías:
Usamos la directiva @foreach para recorrer las categorías
Ejemplo
Un ejemplo de tal relación es un usuario que puede tener múltiples roles, donde el rol también está conectado con múltiples usuarios.
Crearemos las tablas "usuarios", "roles" y "role_user". cada tabla está conectada entre sí. Crearemos relaciones de muchos a muchos entre sí usando el modelo elocuente de laravel. Primero crearemos la migración de la base de datos, luego modelaremos, recuperaremos registros y luego cómo crear registros también. Entonces también puede ver la estructura de la tabla de la base de datos en la pantalla a continuación.
La relación de muchos a muchos utilizará "belongsToMany()" para la relación.
Crear Migraciones
Ahora tenemos que crear la migración de la tabla "usuarios", "roles" y "role_user". también agregaremos la clave externa con la tabla de usuarios y roles. así que vamos a crear como a continuación:
Migración de la tabla users:
Migración de la tabla de roles:
Migración de la tabla role_user:
Crear modelos:
Aquí, crearemos el modelo de tabla User, Role y UserRole. también usaremos "belongsToMany()" para la relación de ambos modelos.
Modelo User:
Modelo Role
Modelo UserRole:
Recuperar registros:
Crear registros:
Relaciones Elocuent N:N (muchos a muchos)
Relaciones Elocuent (Tiene muchos a través de la relación utilizará "hasManyThrough()" para la relación.)
Laravel tiene muchos a través de relaciones elocuent
Tiene muchos a través de la relación es un poco complicado entender una forma de acceso directo para acceder a los datos de otra relación de modo.
Ejemplo
Un país está conectado con usuarios y los usuarios con publicaciones, entonces podemos acceder a todas las publicaciones conectadas con un país específico. tiene muchas relaciones a través de la migración con un esquema de clave externa para relaciones de uno a muchos, crear registros, adjuntar registros, obtener todos los registros, dónde está la condición y todo lo relacionado con tiene muchas a través de la relación.
En este ejemplo, crearé tablas de "usuarios", "publicaciones" y "países". cada tabla está conectada entre sí. ahora crearemos una relación de muchos a muchos entre sí usando el modelo elocuente de laravel.
Tiene muchos a través de la relación utilizará "hasManyThrough()" para la relación.
Crear Migraciones:
Ahora tenemos que crear la migración de la tabla "User", "Post" y "Country". también agregaremos la clave externa con la tabla de usuarios y publicaciones. así que vamos a crear como a continuación:
Migración de la tabla users :
Migración de la tabla posts:
Migración de la tabla countries:
Crear Modelos
Aquí, crearemos el modelo de Coantry. también usaremos "hasManyThrough()" para la relación de ambos modelos.