Foros del Web » Programando para Internet » PHP » Frameworks y PHP orientado a objetos »

Laravel error if en relationship

Estas en el tema de Laravel error if en relationship en el foro de Frameworks y PHP orientado a objetos en Foros del Web. El dia de hoy me he topado con un error algo curioso que no he savido solventar directamente con eloquent., Verán tengo la siguiente función ...
  #1 (permalink)  
Antiguo 25/07/2018, 23:51
Avatar de ArturoGallegos
Moderador
 
Fecha de Ingreso: febrero-2008
Ubicación: Morelia, México
Mensajes: 6.774
Antigüedad: 16 años, 1 mes
Puntos: 1146
Laravel error if en relationship

El dia de hoy me he topado con un error algo curioso que no he savido solventar directamente con eloquent.,



Verán tengo la siguiente función para obtener los detalles de un inventario y sus ventas filtrado o no por vendedor
Relacion en inventario:
Código PHP:
Ver original
  1. public function Ventas(){
  2.         return $this->hasMany('App\Ventas', 'inventario_id');
  3.     }
Funcion en controlador

Código PHP:
Ver original
  1. public function detalle_evento($inventario_id, $vendedor = false){
  2.     $inventario = Inventario::where('id', $inventario_id);
  3.     if($vendedor){
  4.         $inventario = $inventario->with(['Ventas' => function($query) use($vendedor){
  5.             $query->where('vendedor', $vendedor);
  6.         }]);
  7.     }else{
  8.         $inventario = $inventario->with('Ventas');
  9.     }
  10.     return $inventario->first();
  11. }


Hasta aqui todo Ok, mando llamar la funcion dentro de otra funcion que genera la vista y hago un return en ese momento para verificar los datos, me las ventas filtradas por ID de vendedor en json dado que no he imprimido la vista.... Magnifico

Código PHP:
Ver original
  1. return $evento = $this->detalle_evento($inventario_id, $request->vendedor);


Pero requiero hacer un par de operaciones extra
Código PHP:
Ver original
  1. foreach ($evento->ventas as $venta) {
  2. //.... aqui mis operaciones
  3. }
  4. return $evento;




Aquí es donde me quedo de 6.... me retorna todas las ventas sin filtrar, a lo que me pregunto como diablos es que tengo todas las ventas alli si anteriormente ya habian sido filtradas... ¿como lo soluciono?


he intentado crear un array independiente utilizando el mismo foreach conque hago las operaciones extra, pero obvio no funciona, al hacer el foreach ya tiene todo sin filtrar.


Inclusive a modo de prueba hice esto, todo bien, filtrado como debe.

Código PHP:
Ver original
  1. public function test(){
  2. return $evento = $this->detalle_evento(1, 4);
  3. }


Luego esto, ERROR, datos sin filtrar.
Código PHP:
Ver original
  1. public function test(){
  2. $evento = $this->detalle_evento(1, 4);
  3. return $evento->ventas;
  4. }


En el momento que doy entre a la siguiente linea ya me muestra todo sin filtrar
  #2 (permalink)  
Antiguo 26/07/2018, 09:01
Avatar de ArturoGallegos
Moderador
 
Fecha de Ingreso: febrero-2008
Ubicación: Morelia, México
Mensajes: 6.774
Antigüedad: 16 años, 1 mes
Puntos: 1146
Respuesta: Laravel error if en relationship

Solucion temporal al problema aunque no me guste mucho el metodo/forma en que lo he hecho.
Código PHP:
Ver original
  1. public function test(Request $request){
  2.   $evento = $this->detalle_evento($request->inventario_id, $request->vendedor);
  3.   foreach($evento->ventas as $key=>$venta){
  4.     if(isset($request->vendedor) && $venta->vendedor !== $request->vendedor){
  5.       unset($evento->ventas[$key]);
  6.     }
  7.   }
  8.   return $evento->ventas;
  9. }
  #3 (permalink)  
Antiguo 26/07/2018, 10:21
Avatar de hhs
hhs
Colaborador
 
Fecha de Ingreso: junio-2013
Ubicación: México
Mensajes: 2.995
Antigüedad: 10 años, 9 meses
Puntos: 379
Respuesta: Laravel error if en relationship

El error es porque estas usando asignación dentro del if y no es necesario
Código PHP:
Ver original
  1. public function detalle_evento($inventario_id, $vendedor = false){
  2.     $inventario = Inventario::where('id', $inventario_id);
  3.     if($vendedor){
  4.         $inventario->with(['Ventas' => function($query) use($vendedor){
  5.             $query->where('vendedor', $vendedor);
  6.         }]);
  7.     }else{
  8.         $inventario->with('Ventas');
  9.     }
  10.     return $inventario->first();
  11. }
La razón de no usar la asignación es porque el resultado de la primera senctencia es un objeto Builder y hasta que no hagas un first, get o find puedes seguir armando el query

Tambien puedes usar when para sustituir el if. Por otro lado supongo que la segunda función esta como método del controller si es así separa todo en una nueva clase.
También hecha un vistazo al tema de pruebas en Laravel; te hacen la vida mucho mas sencilla
__________________
Saludos
About me
Laraveles
A class should have only one reason to change.
  #4 (permalink)  
Antiguo 26/07/2018, 12:42
Avatar de ArturoGallegos
Moderador
 
Fecha de Ingreso: febrero-2008
Ubicación: Morelia, México
Mensajes: 6.774
Antigüedad: 16 años, 1 mes
Puntos: 1146
Respuesta: Laravel error if en relationship

Negativo, he probado como tu dices y obtengo el mismo resultado, hasta donde tengo entendido hacer la asignación no debería alterar el resultado pero igual lo probé sin asignación y sigue dando el mismo problema tal cual.

Utilizando el método When, he ahorrado código aunque el problema tampoco se solvento con este
Código PHP:
Ver original
  1. public function detalle_evento($inventario_id, $vendedor = false){
  2.         return Inventario::where('id', $inventario_id)->when($vendedor, function ($query, $vendedor){
  3.             $query->with(['Ventas' => function($query) use($vendedor){
  4.                 $query->where('vendedor', $vendedor);
  5.             }]);
  6.         }, function ($query){
  7.             $query->with('Ventas');
  8.         })->first();
  9.     }

Última edición por ArturoGallegos; 26/07/2018 a las 12:47
  #5 (permalink)  
Antiguo 26/07/2018, 13:28
Avatar de hhs
hhs
Colaborador
 
Fecha de Ingreso: junio-2013
Ubicación: México
Mensajes: 2.995
Antigüedad: 10 años, 9 meses
Puntos: 379
Respuesta: Laravel error if en relationship

Eso es muy raro, para que te regrese sin filtro tendría que estar pasando por alto la condición o estas pasando por alto algo mas que no sabemos. Puedes proporcionar mas info?; muestra tu controller la relación entre modelos, porque asi como esta la consulta debe de funcionar sin problema.
__________________
Saludos
About me
Laraveles
A class should have only one reason to change.

Última edición por hhs; 26/07/2018 a las 14:34
  #6 (permalink)  
Antiguo 26/07/2018, 15:27
Avatar de ArturoGallegos
Moderador
 
Fecha de Ingreso: febrero-2008
Ubicación: Morelia, México
Mensajes: 6.774
Antigüedad: 16 años, 1 mes
Puntos: 1146
Respuesta: Laravel error if en relationship

Pues acabo de limpiar todo para hacer la prueba y sigo con los mismos resultados, asi es como quedaron los modelos y el controlador, practicamente nada.

Modelo Inventario:
Código PHP:
Ver original
  1. <?php
  2.  
  3. namespace App;
  4.  
  5. use Illuminate\Database\Eloquent\Model;
  6. use Illuminate\Database\Eloquent\ModelNotFoundException;
  7.  
  8. class Inventario extends Model
  9. {
  10.     protected $table = 'inventario_2';
  11.  
  12.     protected $casts = array(
  13.         'ids' => 'array',
  14.     );
  15.  
  16.     public function getProductos(){
  17.         return $this->hasManyThrough('App\Productos', 'App\InventarioProductosPivote',
  18.             'inventario_id', 'id', 'id', 'producto_id');
  19.     }
  20.  
  21.     public function Ventas(){
  22.         return $this->hasMany('App\Ventas', 'inventario_id');
  23.     }
  24. }

Modelo Ventas:
Código PHP:
Ver original
  1. <?php
  2.  
  3. namespace App;
  4.  
  5. use Illuminate\Database\Eloquent\Model;
  6.  
  7. class Ventas extends Model
  8. {
  9.     public function getInventario(){
  10.         return $this->hasOne('App\Inventario', 'id', 'inventario_id');
  11.     }
  12.  
  13.     public function Pagos(){
  14.         return $this->hasMany('App\Pagos', 'venta_id');
  15.     }
  16.  
  17.     public function Articulos(){
  18.         return $this->hasMany('App\VentaArticulos', 'venta_id');
  19.     }
  20. }

Controlador:
Código PHP:
Ver original
  1. <?php
  2.  
  3. namespace App\Http\Controllers;
  4.  
  5. use App\Inventario;
  6. use Illuminate\Http\Request;
  7.  
  8. class InventarioController extends Controller
  9. {
  10.     public function detalle_evento($evento_id, $vendedor = false){
  11.         return Inventario::where('id', $evento_id)->when($vendedor, function ($query, $vendedor){
  12.             $query->with(['Ventas' => function($query) use($vendedor){
  13.                 $query->where('vendedor', $vendedor);
  14.             }, 'Ventas.Articulos']);
  15.         }, function ($query){
  16.             $query->with('Ventas', 'Ventas.Articulos');
  17.         })->first();
  18.     }
  19.  
  20.     public function detalle_evento_view_imprimir($evento_id, Request $request){
  21.       return $evento = $this->detalle_evento($evento_id, $request->vendedor);// si hago el return aqui el filtro se respeta
  22.       return $evento->ventas;// si hago el return aqui el filtro se ignora ,  porque???'
  23.     }
  24. }
  #7 (permalink)  
Antiguo 26/07/2018, 21:47
Avatar de hhs
hhs
Colaborador
 
Fecha de Ingreso: junio-2013
Ubicación: México
Mensajes: 2.995
Antigüedad: 10 años, 9 meses
Puntos: 379
Respuesta: Laravel error if en relationship

Ya no alcanzo a hacer pruebas el día de hoy, pero de entrada algunas relaciones no son correctas
por ejemplo esta:
Código PHP:
Ver original
  1. public function getProductos(){
  2.         return $this->hasManyThrough('App\Productos', 'App\InventarioProductosPivote',
  3.             'inventario_id', 'id', 'id', 'producto_id');
  4.     }
hasManyTrough solo es para relaciones 1 a N si tu relación en los modelos es N a M entonces tienes que usar belongsToMany.

Tambien la relación de invetario a ventas la colocas como hasMany, pero desde ventas la poner como hasOne y debe de ser belongsTo
Código PHP:
Ver original
  1. public function getInventario(){
  2.         return $this->hasOne('App\Inventario', 'id', 'inventario_id');
  3.     }
Esto debe de ser belongsTo ya que es el lado inverso de la relación 1 a N.
Verifica esas relaciones ya que puedes tener resultados inesperados si los dejas como están.
__________________
Saludos
About me
Laraveles
A class should have only one reason to change.
  #8 (permalink)  
Antiguo 31/07/2018, 09:14
Avatar de hhs
hhs
Colaborador
 
Fecha de Ingreso: junio-2013
Ubicación: México
Mensajes: 2.995
Antigüedad: 10 años, 9 meses
Puntos: 379
Respuesta: Laravel error if en relationship

Realice algunas pruebas simulando un poco tus modelos y no obtengo el comportamiento que tienes a la hora de hacer el eager loading y obtener solo las ventas que tienen un vendedor. No se si obtuviste otro resultado con lo que te comente de las relaciones ?
__________________
Saludos
About me
Laraveles
A class should have only one reason to change.
  #9 (permalink)  
Antiguo 01/08/2018, 20:29
Avatar de ArturoGallegos
Moderador
 
Fecha de Ingreso: febrero-2008
Ubicación: Morelia, México
Mensajes: 6.774
Antigüedad: 16 años, 1 mes
Puntos: 1146
Respuesta: Laravel error if en relationship

Buen día @HHS

Perdón por la demora, sobre las migraciones cumplen su cometido así como están, eso si, como bien dices con ese modelo y controlador funciona.

He hecho una instalación agregando unicamente dichos modelos y controladores y funciona todo correcto, así que algo mas esta interfiriendo aunque no lo vea., ya que se me han pedido mas cosas para el proyecto estoy mudando todo poco a poco a la nueva instalación, cuando encuentre la causa la comparto.

Muchas gracias por tu paciencia y tiempo.
  #10 (permalink)  
Antiguo 03/08/2018, 11:27
Avatar de hhs
hhs
Colaborador
 
Fecha de Ingreso: junio-2013
Ubicación: México
Mensajes: 2.995
Antigüedad: 10 años, 9 meses
Puntos: 379
Respuesta: Laravel error if en relationship

Vaya que curioso, si no es evidente el problema puede ser algo en la lógica en algún punto de la aplicación, espero que encuentres donde esta, sería interesante saber como es que esta afectando el resultado.
__________________
Saludos
About me
Laraveles
A class should have only one reason to change.

Etiquetas: laravel
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 05:18.