Sunteți pe pagina 1din 11

Relaciones Eloquent clásicas

Comúnmente solemos relacionar nuestro modelos Eloquent de la siguiente


forma:

class Author extends Model

public function books()

return $this->hasMany(Book::class);

Y luego solemos mostrar los resultados de la relación Eloquent de la


siguiente forma:

$authors = Author::all();

foreach ($authors as $author) {

foreach ($author->books as $book) {

// ...

Más allá que esta no es la mejor forma de obtener los resultados de una
relación (luego veremos la forma correcta). Pero, ¿cómo podríamos hacer si
queremos obtener los libros que se escribieron en el último mes?
Una forma es agregar un filtro en la relación para obtener los libros del último
mes:

public function books()

return $this->hasMany(Book::class)

->whereMonth('books.created_at', date('m'));

Si quieres saber mas sobre filtros de fechas como whereMonth(), puedes ver el
siguiente articulo, Buscar registros por fechas con Laravel Eloquent

Pero, esta no es la mejor opción para filtrar la relación ya que, siempre que
obtengamos los libros serán filtrados por el mes actual.

Así que, la mejor opción es crear una nueva relación, además de la


relación books() de la siguiente forma:

public function books()

return $this->hasMany(Book::class);

public function booksThisMonth()

{
return $this->hasMany(Book::class)

->whereMonth('books.created_at', date('m'));

Y luego obtener los resultados de la siguiente forma:

$authors = Author::all();

foreach ($authors as $author) {

foreach ($author->booksThisMonth as $book) {

// ...

Optimizando consulta Eloquent con relaciones

Como dije anteriormente, la forma que estamos obteniendo los autores con
sus libros no es la forma de optima de hacerlo.

Eloquent nos provee el método with() que nos permite integrar la relación de
libros a cada uno de los autores, todo en consultas SQL optimizadas.

$authors = Author::with('booksThisMonth')->get();

Esta es la mejor forma de aplicar filtros a relaciones Eloquent, porque


con código limpio y optimizado, estamos obteniendo los autores que tienen
libros escritos en el mes actual.

Filtro dinámico en relaciones Eloquent


Por otro lado, si queremos agregar una mayor flexibilidad a nuestro filtro,
podemos utilizar una variable que contenga un valor (en mi ejemplo, el
numero del mes) para parametrizar el filtro. Pero, no utilizaremos nuestra
relación booksThisMonth(), si no que vamos utilizar nuestra
relación books() de la siguiente forma:

$month = 12;

$authors = Author::with(['books' => function($query) use ($month) {

$query->whereMonth('created_at', $month);

}])->get();

use la clase User y el método with que laravel tiene para consultar las relaciones del
modelo

$user = User::with(['profile', 'friend'])->get();

Asegúrese de que sus modelos tengan las relaciones correctas de la siguiente


manera:

app/models/User.php

public function friend () {

return $this->hasMany('friend');

public function profile () {

return $this->hasOne('profile');

app/models/Profile.php

public function user() {

return $this->belongsTo('User');
}

app/models/Friend.php

public function user() {

return $this->belongsTo('user');

$beneficiarios = Departamento::whereHas('municipio', function($q) {


$q->where('departamento_id', Input::get('depto'));
})
->with(['corregimiento', 'barrio', 'beneficiario'])
->get();

Tengo una tabla de productos que tiene los campos:

id, nombre, precio, id_categoria


Y tengo la tabla de categoria con los campos:

id, nombre

public function productos()


{
return $this->hasMany(Producto::class);
}

public function categoria()


{
return $this->belongsTo(Categoria::class);
}

@foreach($productos as $producto)
{{ $producto->nombre }}
{{ $producto->precio }}
{{ $producto->categoria->name }}
@endforeach

$products = Productos::join('Categorias','idCategoria', '=', 'Categorias.id')-


>select('Productos.id','Productos.nombre','Categorias.nombre as NombreCategoria')->get();

public function categoria()


{
return $this->belongsTo(Categoria::class, 'idCategoria');
}

Prueba usar el método pluck para extraer sólo los datos que quieres
ejemplo: Productos::with('categoria')->pluck('nombre')->get();

"Productos::with('categoria')->pluck('categoria.nombre')->get();"

public function index()


{
$mapas = Mapa::orderBy('id', 'DESC')->where('user_id', auth()->user()->id);
$marcadores = Marcador::orderBy('id', 'DESC')->where('mapa_id');
return view('user.marcadores.index', compact('marcadores'));
}
class Mapa extends Model
{
/**
* Get the comments for the blog post.
*/
public function marcadores()
{
return $this->hasMany('TuModeloMarcadores');
}
}
Mapa::with('marcadores')->orderBy('id', 'DESC')->where('user_id', auth()-
>user()->id);
Y luego accede a los marcadores del mapa así.

foreach ($mapas as $mapa) {


$mapa->marcadores
}

class Mapa extends Model


{
/**
* Obtener los marcadores.
*/
public function marcadores()
{
return $this->hasMany(Marcadores::class);
}
}
Luego, en tu controlador:

public function index()


{
$marcadores = Mapa::with('marcadores')
->orderBy('id', 'DESC')
->where('user_id', auth()->id()) // equivalente a auth()->user()->id
->get() // hasta acá ya cargamos los mapas con sus marcadores
->flatMap(function ($mapa) {
return $mapa->marcadores;
}); // con esto estamos extrayendo los marcadores y compactando el array

return view('user.marcadores.index', ['marcadores' => $marcadores]);


}
Tabla de categorías
id
category_name

Tabla de usuario
id
user_name
user_type

Tabla de artículos
id
title
body
categories_id
user_id

1) Categoría (tiene muchos artículos)

2) Usuario (tiene muchos artículos)

3) Artículo (pertenece al usuario y categoría)

1) category.php
< ?php namespace App\Models;
use Eloquent;
class Category extends Eloquent {
protected $table = "categories";
public function articles() {
return $this->hasMany('App\Models\Article');
}
}
2) User.php
< ?php namespace App\Models;
use Eloquent;
class User extends Eloquent {
protected $table = 'users';
public function articles() {
return $this->hasMany('App\Models\Article');
}
}
3) Article.php
< ?php namespace App\Models;
use Eloquent;
class Article extends Eloquent{
protected $table = 'articles';

public function user() {


return $this->belongsTo('App\Models\User');
}
public function category() {
return $this->belongsTo('App\Models\Category');
}

Consultas
si desea recuperar un artículo utilizando el usuario y la categoría
$article = \App\Models\Article::with(['user','category'])->first();

y puedes usar esto como


//retrieve user name $article->user->user_name
//retrieve category name $article->category->category_name

en otro caso, es posible que necesite recuperar todos los artículos dentro de una categoría
o recuperar todos los artículos de un usuario específico; puedes escribirlo así:

$categories = \App\Models\Category::with('articles')->get();
$users = \App\Models\Category::with('users')->get();

Tartar:
$articles = DB::table('articles') ->select('articles.id as articles_id', ..... )
->join('categories', 'articles.categories_id', '=', 'categories.id') -
>join('users', 'articles.user_id', '=', 'user.id') ->get();
Así quedaron los modelos:
Users:
protected $table = 'users';
public function Places() {
return $this->hasMany('Place','id_user', 'id');
}

Place:

protected $table = 'places';


public function Reservations() {
return $this->hasOne('Reservation','id_place', 'id');
}
public function Users() {
return $this->hasOne('User','id', 'id_user');
}

Reservation:

protected $table = 'reservations';


public function Places() {
return $this->hasMany('Place','id', 'id_place');
}

public function Payments() {


return $this->hasMany('Payment', 'id_reservation','id');
}

public function Usersclient() {


return $this->hasMany('User', 'id','id_client');
}

public function Usershost() {


return $this->hasMany('User', 'id','id_host');
}

Payment:

protected $table = 'payments';


public function Reservations() {
return $this->belongsTo('Reservation');
}
La consulta quedaria asi:
$reservations = Reservation::with("Places")->with("Payments")
->with("Usersclient")

->with("Usershost")

->where(['id_host'=>$id_host])

->orderBy('reservation_date','desc')

->paginate(2);