当关系不存在时,渴望加载关系

时间:2016-01-28 06:44:42

标签: laravel laravel-5 eloquent

所以,我有一个Product模型belongsTo('App\Tax')Product可能与Tax关联,也可能不关联(tax_id中的Product fk可能为空。)

只要我至少有一个ProductTax相关联,下面的查询就可以正常工作:

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

Product没有关联Tax时,它会开始抛出以下异常:

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))'

虽然这个例外是可以理解的,但我的问题是如何避免这种情况?

注意:tax.id列属于postgres uuid类型。

编辑1

我应该明确提到我正在尝试编写一个查询来获取属于特定Product的所有Organization,无论它们是否与Tax相关联。

只要至少有一个ProductTax相关联,上述查询就可以正常运行。如果所有产品(1个或更多)与任何税收无关,则抛出QueryException

编辑2

所以,我得到了一个有效的解决方案。我仍然愿意接受更好的解决方案。以下是我如何使用它:

// 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);
    }
}

这给了我所有产品,即使它们都没有关联关系。

2 个答案:

答案 0 :(得分:0)

你可以采取多种方式。

  1. 使用\App\Product::has('tax')->whith('tax')->get();它将获得至少有一个Tax
  2. 的产品
  3. 基于关系条件 \App\Product::whereHas('tax', function ($query) { $query->where('content', 'like', 'foo%'); })->whith('tax')->get();
  4. \App\Product::with(['tax' => function ($query) { $query->whereNotNull('product_id'); }])->get();但有子查询,其中product_id不为空;
  5. $products = \App\Product::get(); if ($products->tax()->count() > 0) { $products->load('tax'); }
  6. 延迟加载计算产品税,如果大于0,则延迟加载它们 希望它有所帮助!

答案 1 :(得分:0)

我不想回答我自己的问题,但由于我没有收到任何答案,我自己发布了一个,为了可能涉及的任何人的利益。

我找到了一个可行的解决方案,这看起来并不合适。我仍然愿意接受更好的解决方案。以下是我如何使用它:

// 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);
    }
}

这给了我所有产品,即使它们都没有关联关系。