Entonces, tengo un modelo Product que belongsTo('App\Tax'). Un Product puede o no estar asociado con un Tax (el tax_id fk en Product podría ser nulo).

La consulta a continuación funciona bien siempre que tenga al menos un Product asociado con un Tax:

\App\Product::with("tax")->get()

Comienza a lanzar la siguiente excepción, cuando ninguno de los Product tiene Tax asociados:

Illuminate\Database\QueryException with message 'SQLSTATE[22P02]: Invalid text 
representation: 7 ERROR:  invalid input syntax for uuid: "0" (SQL: select * 
from "taxes" where "taxes"."id" in (0))'

Si bien esta excepción es bastante comprensible, mi pregunta es ¿cómo evito esta situación?

Nota: La columna tax.id es de tipo postgres uuid.

EDITAR 1

Debo mencionar explícitamente que estoy tratando de escribir una consulta para obtener todos los Product s, que pertenecen a un Organization en particular, ya sea que estén asociados con un Tax o no.

La consulta anterior funciona bien siempre que haya al menos un Product asociado con un Tax. Lanza QueryException si todos los productos (1 o más), no están asociados con ningún impuesto.

EDITAR 2

Entonces, tengo una solución que funciona, que no parece del todo correcta. Todavía estoy abierto a una mejor solución. Así es como lo hice funcionar:

// First just fetch all the products using whatever criterion
$products = $query
    ->orderBy ($params["orderBy"], $params["sortDir"])
    ->skip ($params["start"])
    ->take ($params["length"])
    ->get();

// Then, load the relation, if there's at least one product having
// that relation. 
// Solution requires one additional aggregate query per relation
// than a regular with() clause would have generated
$relations = array('purchase_tax', 'sale_tax', 'category');
foreach($relations as $relation) {
    $count = $org->products()
        ->whereHas($relation, function($query){
            $query->whereNotNull('id');
        })
        ->count();
    if ($count) {
        $products->load($relation);
    }
}

Esto me da todos los productos, incluso si ninguno de ellos tiene las relaciones asociadas.

0
Code Poet 28 ene. 2016 a las 09:44

2 respuestas

La mejor respuesta

No me gusta contestar mis propias preguntas, pero como no he recibido ninguna respuesta, publico una yo mismo, para beneficio de quien corresponda.

Tengo una solución que funciona, que no parece del todo correcta. Todavía estoy abierto a una mejor solución. Así es como lo hice funcionar:

// First just fetch all the products using whatever criterion
$products = $query
    ->orderBy ($params["orderBy"], $params["sortDir"])
    ->skip ($params["start"])
    ->take ($params["length"])
    ->get();

// Then, load the relation, if there's at least one product having
// that relation. 
// Solution requires one additional aggregate query per relation
// than a regular with() clause would have generated
$relations = array('purchase_tax', 'sale_tax', 'category');
foreach($relations as $relation) {
    $count = $org->products()
        ->whereHas($relation, function($query){
            $query->whereNotNull('id');
        })
        ->count();
    if ($count) {
        $products->load($relation);
    }
}

Esto me da todos los productos, incluso si ninguno de ellos tiene las relaciones asociadas.

0
Code Poet 29 ene. 2016 a las 18:37

Puedes ir de muchas maneras.

  1. El uso tiene \App\Product::has('tax')->whith('tax')->get(); Obtendrá productos que tengan al menos un Tax
  2. basado en la condición para la relación \App\Product::whereHas('tax', function ($query) { $query->where('content', 'like', 'foo%'); })->whith('tax')->get();
  3. \App\Product::with(['tax' => function ($query) { $query->whereNotNull('product_id'); }])->get(); Con pero subconsulta donde product_id no es nulo;
  4. $products = \App\Product::get(); if ($products->tax()->count() > 0) { $products->load('tax'); }

Carga diferida Cuente el impuesto sobre el producto y si es mayor a 0, cárguelos diferidos ¡Espero que ayude!

0
Froxz 28 ene. 2016 a las 07:25